diff --git a/.github/workflows/flawfinder.yml b/.github/workflows/flawfinder.yml index 8b869234..dfa6d337 100644 --- a/.github/workflows/flawfinder.yml +++ b/.github/workflows/flawfinder.yml @@ -11,8 +11,6 @@ on: pull_request: # The branches below must be a subset of the branches above branches: [ "master" ] - schedule: - - cron: '21 1 * * 1' jobs: flawfinder: diff --git a/.gitignore b/.gitignore index 7379e127..6ebb98d0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ *.map *.fsys *.log -.dccache diff --git a/.vscode/c_boilerplates.code-snippets b/.vscode/c_boilerplates.code-snippets index 8ea597c9..972e73e7 100644 --- a/.vscode/c_boilerplates.code-snippets +++ b/.vscode/c_boilerplates.code-snippets @@ -5,20 +5,20 @@ ], "body": [ "/*", - " This file is part of Fennix Kernel.", + "\tThis file is part of Fennix Kernel.", "", - " Fennix Kernel is free software: you can redistribute it and/or", - " modify it under the terms of the GNU General Public License as", - " published by the Free Software Foundation, either version 3 of", - " the License, or (at your option) any later version.", + "\tFennix Kernel is free software: you can redistribute it and/or", + "\tmodify it under the terms of the GNU General Public License as", + "\tpublished by the Free Software Foundation, either version 3 of", + "\tthe License, or (at your option) any later version.", "", - " Fennix Kernel is distributed in the hope that it will be useful,", - " but WITHOUT ANY WARRANTY; without even the implied warranty of", - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", - " GNU General Public License for more details.", + "\tFennix Kernel is distributed in the hope that it will be useful,", + "\tbut WITHOUT ANY WARRANTY; without even the implied warranty of", + "\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", + "\tGNU General Public License for more details.", "", - " You should have received a copy of the GNU General Public License", - " along with Fennix Kernel. If not, see .", + "\tYou should have received a copy of the GNU General Public License", + "\talong with Fennix Kernel. If not, see .", "*/", "", "#ifndef __FENNIX_KERNEL_${2:header}_H__", @@ -60,20 +60,20 @@ ], "body": [ "/*", - " This file is part of Fennix Kernel.", + "\tThis file is part of Fennix Kernel.", "", - " Fennix Kernel is free software: you can redistribute it and/or", - " modify it under the terms of the GNU General Public License as", - " published by the Free Software Foundation, either version 3 of", - " the License, or (at your option) any later version.", + "\tFennix Kernel is free software: you can redistribute it and/or", + "\tmodify it under the terms of the GNU General Public License as", + "\tpublished by the Free Software Foundation, either version 3 of", + "\tthe License, or (at your option) any later version.", "", - " Fennix Kernel is distributed in the hope that it will be useful,", - " but WITHOUT ANY WARRANTY; without even the implied warranty of", - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", - " GNU General Public License for more details.", + "\tFennix Kernel is distributed in the hope that it will be useful,", + "\tbut WITHOUT ANY WARRANTY; without even the implied warranty of", + "\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", + "\tGNU General Public License for more details.", "", - " You should have received a copy of the GNU General Public License", - " along with Fennix Kernel. If not, see .", + "\tYou should have received a copy of the GNU General Public License", + "\talong with Fennix Kernel. If not, see .", "*/" ], "description": "Create kernel license." diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 0f69fa87..8fb6c526 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -52,7 +52,7 @@ "-fno-exceptions", // Linker flags - "-T${workspaceFolder}/Architecture/amd64/linker.ld", + "-T${workspaceFolder}/arch/amd64/linker.ld", "-Wl,-static,--no-dynamic-linker,-ztext", "-nostdlib", "-nodefaultlibs", @@ -130,7 +130,7 @@ "-fno-exceptions", // Linker flags - "-T${workspaceFolder}/Architecture/i386/linker.ld", + "-T${workspaceFolder}/arch/i386/linker.ld", "-Wl,-static,--no-dynamic-linker,-ztext", "-nostdlib", "-nodefaultlibs", @@ -201,7 +201,7 @@ "-fno-exceptions", // Linker flags - "-T${workspaceFolder}/Architecture/aarch64/linker.ld", + "-T${workspaceFolder}/arch/aarch64/linker.ld", "-fPIC", // Debug flags diff --git a/Architecture/aarch64/Entry.cpp b/Architecture/aarch64/Entry.cpp deleted file mode 100644 index 857cea09..00000000 --- a/Architecture/aarch64/Entry.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -EXTERNC void arm64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3) -{ - trace("Hello, World!"); - CPU::Halt(true); -} diff --git a/Architecture/aarch64/Memory/VirtualMemoryManager.cpp b/Architecture/aarch64/Memory/VirtualMemoryManager.cpp deleted file mode 100644 index 00c00e49..00000000 --- a/Architecture/aarch64/Memory/VirtualMemoryManager.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -namespace Memory -{ - bool Virtual::Check(void *VirtualAddress, PTFlag Flag, MapType Type) - { - } - - void *Virtual::GetPhysical(void *VirtualAddress) - { - } - - void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type) - { - } - - void Virtual::Unmap(void *VirtualAddress, MapType Type) - { - } -} diff --git a/Architecture/aarch64/SystemCalls.cpp b/Architecture/aarch64/SystemCalls.cpp deleted file mode 100644 index aea86378..00000000 --- a/Architecture/aarch64/SystemCalls.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include - -extern "C" __naked __used __no_stack_protector void SystemCallHandlerStub() -{ - -} - -extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs); - -void InitializeSystemCalls() -{ -} diff --git a/Architecture/aarch64/cpu/SymmetricMultiprocessing.cpp b/Architecture/aarch64/cpu/SymmetricMultiprocessing.cpp deleted file mode 100644 index f6c89b95..00000000 --- a/Architecture/aarch64/cpu/SymmetricMultiprocessing.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include -#include - -#include "../../../kernel.h" - -volatile bool CPUEnabled = false; - -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -static __aligned(0x1000) CPUData CPUs[MAX_CPU] = {0}; - -CPUData *GetCPU(uint64_t id) { return &CPUs[id]; } - -CPUData *GetCurrentCPU() -{ - uint64_t ret = 0; - - if (!CPUs[ret].IsActive) - { - error("CPU %d is not active!", ret); - return &CPUs[0]; - } - - if (CPUs[ret].Checksum != CPU_DATA_CHECKSUM) - { - error("CPU %d data is corrupted!", ret); - return &CPUs[0]; - } - return &CPUs[ret]; -} - -namespace SMP -{ - int CPUCores = 0; - - void Initialize(void *madt) - { - fixme("SMP::Initialize() is not implemented!"); - } -} diff --git a/Architecture/aarch64/linker.ld b/Architecture/aarch64/linker.ld deleted file mode 100644 index 0349abcc..00000000 --- a/Architecture/aarch64/linker.ld +++ /dev/null @@ -1,90 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -ENTRY(_start) - -SECTIONS -{ - _bootstrap_start = .; - .text.boot : - { - *(.text.boot) - . += CONSTANT(MAXPAGESIZE); - _bss_start = .; - *(.text.bss) - _bss_end = .; - } - _bootstrap_end = .; - - _kernel_start = .; - _kernel_text_start = .; - .text : - { - KEEP(*(.text.boot)) - *(.text .text.*) - } - . = ALIGN(4096); - _kernel_text_end = .; - - _kernel_data_start = .; - .data : - { - *(.data .data.*) - } - . = ALIGN(4096); - _kernel_data_end = .; - - _kernel_rodata_start = .; - .rodata : - { - *(.rodata .rodata.*) - } - . = ALIGN(4096); - - .init_array : - { - PROVIDE_HIDDEN(__init_array_start = .); - KEEP(*(.init_array .ctors)) - KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - PROVIDE_HIDDEN (__init_array_end = .); - } - - .fini_array : - { - PROVIDE_HIDDEN(__fini_array_start = .); - KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP(*(.fini_array .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } - _kernel_rodata_end = .; - - _kernel_bss_start = .; - .bss : - { - *(.bss .bss.*) - } - . = ALIGN(4096); - _kernel_bss_end = .; - _kernel_end = .; - _bss_size = _kernel_end - _kernel_rodata_end; - - /DISCARD/ : - { - *(.comment*) - *(.note*) - } -} diff --git a/Architecture/amd64/Bootstrap/Multiboot/Headers/Header1.s b/Architecture/amd64/Bootstrap/Multiboot/Headers/Header1.s deleted file mode 100644 index 087ee5fa..00000000 --- a/Architecture/amd64/Bootstrap/Multiboot/Headers/Header1.s +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.code32 -.extern Multiboot_start - -.section .multiboot, "a" -.align 4 - -MULTIBOOT_HEADER: - .long 0x1BADB002 - .long 0x1 | 0x2 | 0x4 - .long -(0x1BADB002 + (0x1 | 0x2 | 0x4)) - /* KLUDGE */ - .long 0 - .long 0 - .long 0 - .long 0 - .long 0 - /* VIDEO MODE */ - .long 0 - .long 0 - .long 0 - .long 0 diff --git a/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT32.s b/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT32.s deleted file mode 100644 index 2509ccdb..00000000 --- a/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT32.s +++ /dev/null @@ -1,64 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.code32 -.section .bootstrap.text, "a" - -.align 32 -.global gdtr -gdtr: - .word GDT32_END - GDT32 - 1 - .long GDT32 - -.align 32 -GDT32: - .quad 0x0 - - .word 0xFFFF - .word 0x0000 - .byte 0x00 - .word 0xCF9A - .byte 0x00 - - .word 0xFFFF - .word 0x0000 - .byte 0x00 - .word 0xCF92 - .byte 0x00 - - .word 0x0100 - .word 0x1000 - .byte 0x00 - .word 0x4092 - .byte 0x00 -GDT32_END: - nop - -.global LoadGDT32 -LoadGDT32: - lgdt [gdtr] - ljmp $0x8, $ActivateGDT - -ActivateGDT: - mov $0x10, %cx - mov %cx, %ss - mov %cx, %ds - mov %cx, %es - mov %cx, %fs - mov $0x18, %cx - mov %cx, %gs - ret diff --git a/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT64.s b/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT64.s deleted file mode 100644 index 511355d5..00000000 --- a/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT64.s +++ /dev/null @@ -1,62 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.code64 -.section .bootstrap.data, "a" - -/* Access bits */ -A = 0x1 -RW = 0x2 -DC = 0x4 -E = 0x8 -S = 0x10 -DPL0 = 0x0 /* 0 << 5 ???? */ -DPL1 = 0x20 -P = 0x80 - -/* Flags bits */ -LONG_MODE = 0x20 -SZ_32 = 0x40 -GRAN_4K = 0x80 - -.global GDT64.Null -.global GDT64.Code -.global GDT64.Data -.global GDT64.Tss -.global GDT64.Ptr - -GDT64: -GDT64.Null = . - GDT64 - .quad 0 -GDT64.Code = . - GDT64 - .long 0xFFFF - .byte 0 - .byte P | S | E | RW - .byte GRAN_4K | LONG_MODE | 0xF - .byte 0 -GDT64.Data = . - GDT64 - .long 0xFFFF - .byte 0 - .byte P | S | RW - .byte GRAN_4K | SZ_32 | 0xF - .byte 0 -GDT64.Tss = . - GDT64 - .long 0x00000068 - .long 0x00CF8900 -GDT64.Ptr: - .word . - GDT64 - 1 - .quad GDT64 diff --git a/Architecture/amd64/Bootstrap/_start.s b/Architecture/amd64/Bootstrap/_start.s deleted file mode 100644 index 5e9efa96..00000000 --- a/Architecture/amd64/Bootstrap/_start.s +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.code32 -.extern Multiboot_start - -.section .bootstrap.text, "a" - -.global _start -_start: - /* Check for multiboot */ - cmp $0x2BADB002, %eax - je .Multiboot - - /* Unkown bootloader */ - .Hang: - cli - hlt - jmp .Hang - - /* Multiboot */ - .Multiboot: - call Multiboot_start - jmp .Hang diff --git a/Architecture/amd64/cpu/idt.hpp b/Architecture/amd64/cpu/idt.hpp deleted file mode 100644 index a1ad5dd3..00000000 --- a/Architecture/amd64/cpu/idt.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_IDT_H__ -#define __FENNIX_KERNEL_IDT_H__ - -#include -#include - -namespace InterruptDescriptorTable -{ - - union IDTGateDescriptor - { - InterruptGate Interrupt; - TrapGate Trap; - CallGate Call; - }; - - struct IDTRegister - { - uint16_t Limit; - IDTGateDescriptor *BaseAddress; - } __packed; - - void SetEntry(uint8_t Index, - void (*Base)(), - InterruptStackTableType InterruptStackTable, - GateType Gate, - PrivilegeLevelType Ring, - bool Present, - uint16_t SegmentSelector); - - void Init(int Core); -} - -#endif // !__FENNIX_KERNEL_IDT_H__ diff --git a/Architecture/amd64/linker.ld b/Architecture/amd64/linker.ld deleted file mode 100644 index f0f46822..00000000 --- a/Architecture/amd64/linker.ld +++ /dev/null @@ -1,104 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -OUTPUT_FORMAT(elf64-x86-64) -OUTPUT_ARCH(i386:x86-64) - -ENTRY(_start) - -PF_R = 0x4; -PF_W = 0x2; -PF_X = 0x1; - -PHDRS -{ - bootstrap PT_LOAD FLAGS( PF_R | PF_W /*| PF_X*/ ); - text PT_LOAD FLAGS( PF_R | PF_X ); - data PT_LOAD FLAGS( PF_R | PF_W ); - rodata PT_LOAD FLAGS( PF_R ); - bss PT_LOAD FLAGS( PF_R | PF_W ); -} - -KERNEL_VMA = 0xFFFFFFFF80000000; - -SECTIONS -{ - . = 0x100000; - _bootstrap_start = .; - .bootstrap ALIGN(CONSTANT(MAXPAGESIZE)) : - { - *(.multiboot) - *(.multiboot2) - *(.bootstrap .bootstrap.*) - } :bootstrap - _bootstrap_end = ALIGN(CONSTANT(MAXPAGESIZE)); - - . += KERNEL_VMA; - - _kernel_start = ALIGN(CONSTANT(MAXPAGESIZE)); - _kernel_text_start = ALIGN(CONSTANT(MAXPAGESIZE)); - .text ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.text) - KERNEL_VMA) - { - *(.text .text.*) - } :text - _kernel_text_end = ALIGN(CONSTANT(MAXPAGESIZE)); - - _kernel_data_start = ALIGN(CONSTANT(MAXPAGESIZE)); - .data ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.data) - KERNEL_VMA) - { - *(.data .data.*) - } :data - _kernel_data_end = ALIGN(CONSTANT(MAXPAGESIZE)); - - _kernel_rodata_start = ALIGN(CONSTANT(MAXPAGESIZE)); - .rodata ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.rodata) - KERNEL_VMA) - { - *(.rodata .rodata.*) - } :rodata - - .init_array ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.init_array) - KERNEL_VMA) - { - PROVIDE_HIDDEN(__init_array_start = .); - KEEP(*(.init_array .ctors)) - KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - PROVIDE_HIDDEN (__init_array_end = .); - } :rodata - - .fini_array ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.fini_array) - KERNEL_VMA) - { - PROVIDE_HIDDEN(__fini_array_start = .); - KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP(*(.fini_array .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } :rodata - _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); - - _kernel_bss_start = ALIGN(CONSTANT(MAXPAGESIZE)); - .bss ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.bss) - KERNEL_VMA) - { - *(COMMON) - *(.bss .bss.*) - } :bss - _kernel_bss_end = ALIGN(CONSTANT(MAXPAGESIZE)); - _kernel_end = ALIGN(CONSTANT(MAXPAGESIZE)); - - /DISCARD/ : - { - *(.comment*) - *(.note*) - } -} diff --git a/Architecture/i386/Bootstrap/Multiboot/Headers/Header1.s b/Architecture/i386/Bootstrap/Multiboot/Headers/Header1.s deleted file mode 100644 index 56fff329..00000000 --- a/Architecture/i386/Bootstrap/Multiboot/Headers/Header1.s +++ /dev/null @@ -1,27 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.intel_syntax noprefix - -.code32 -.section .multiboot, "a" -.align 4 - -MULTIBOOT_HEADER: - .long 0x1BADB002 - .long 1 << 0 | 1 << 1 - .long -(0x1BADB002 + (1 << 0 | 1 << 1)) diff --git a/Architecture/i386/Bootstrap/Multiboot/Helper/GDT32.s b/Architecture/i386/Bootstrap/Multiboot/Helper/GDT32.s deleted file mode 100644 index 2509ccdb..00000000 --- a/Architecture/i386/Bootstrap/Multiboot/Helper/GDT32.s +++ /dev/null @@ -1,64 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.code32 -.section .bootstrap.text, "a" - -.align 32 -.global gdtr -gdtr: - .word GDT32_END - GDT32 - 1 - .long GDT32 - -.align 32 -GDT32: - .quad 0x0 - - .word 0xFFFF - .word 0x0000 - .byte 0x00 - .word 0xCF9A - .byte 0x00 - - .word 0xFFFF - .word 0x0000 - .byte 0x00 - .word 0xCF92 - .byte 0x00 - - .word 0x0100 - .word 0x1000 - .byte 0x00 - .word 0x4092 - .byte 0x00 -GDT32_END: - nop - -.global LoadGDT32 -LoadGDT32: - lgdt [gdtr] - ljmp $0x8, $ActivateGDT - -ActivateGDT: - mov $0x10, %cx - mov %cx, %ss - mov %cx, %ds - mov %cx, %es - mov %cx, %fs - mov $0x18, %cx - mov %cx, %gs - ret diff --git a/Architecture/i386/Bootstrap/Multiboot/_start.s b/Architecture/i386/Bootstrap/Multiboot/_start.s deleted file mode 100644 index 5e9efa96..00000000 --- a/Architecture/i386/Bootstrap/Multiboot/_start.s +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -.code32 -.extern Multiboot_start - -.section .bootstrap.text, "a" - -.global _start -_start: - /* Check for multiboot */ - cmp $0x2BADB002, %eax - je .Multiboot - - /* Unkown bootloader */ - .Hang: - cli - hlt - jmp .Hang - - /* Multiboot */ - .Multiboot: - call Multiboot_start - jmp .Hang diff --git a/Architecture/i386/SystemCalls.cpp b/Architecture/i386/SystemCalls.cpp deleted file mode 100644 index cc9c5007..00000000 --- a/Architecture/i386/SystemCalls.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include - -#include "cpu/gdt.hpp" - -using namespace CPU::x32; - -extern "C" uint32_t SystemCallsHandler(SyscallsFrame *regs); - -void InitializeSystemCalls() -{ -} diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 00000000..703a9a23 --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,109 @@ +# Credits and References + +This project has been influenced and inspired by other projects and resources. + +License information can be found in the [LICENSES.md](LICENSES.md) file. + +## General +- [OSDev Wiki](https://wiki.osdev.org/Main_Page) +- [GCC x86 Built-in Functions](https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html#x86-Built-in-Functions) +- [GCC Common Function Attributes](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes) + +## Font +- [Tamsyn Font](http://www.fial.com/~scott/tamsyn-font/) + +## CPU XCR0 Structure +- [CPU Registers x86 - XCR0](https://wiki.osdev.org/CPU_Registers_x86#XCR0) + +## CPUID 0x7 +- [CPUID](https://en.wikipedia.org/wiki/CPUID) + +## Network +- [Beej's Guide to Network Programming](https://web.archive.org/web/20051210132103/http://users.pcnet.ro/dmoroian/beej/Beej.html) +- [UDP Socket Programming](https://web.archive.org/web/20060229214053/http://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html) +- [EtherType](https://en.wikipedia.org/wiki/EtherType) +- [Linux Network Packet Reception](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-network-packet-reception) +- [Linux Kernel Networking Labs](https://linux-kernel-labs.github.io/refs/heads/master/labs/networking.html) +- [smoltcp](https://github.com/smoltcp-rs/smoltcp) +- [Understanding Linux Network Internals](https://www.cs.unh.edu/~cruse/cs326f04/RTL8139D_DataSheet.pdf) +- [Address Resolution Protocol (ARP)](https://en.wikipedia.org/wiki/Address_Resolution_Protocol) +- [C++ Operators](https://en.cppreference.com/w/cpp/language/operators) +- [Dynamic Host Configuration Protocol (DHCP)](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol) +- [RTL8139 Programmer's Guide](https://www.cs.usfca.edu/~cruse/cs326f04/RTL8139_ProgrammersGuide.pdf) +- [RTL8139CP Datasheet](http://realtek.info/pdf/rtl8139cp.pdf) +- [IPv4](https://en.wikipedia.org/wiki/IPv4) +- [ICMP Parameters](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml) + +## Loading ELF Shared Libraries and Dynamic Linking +- [How To Write Shared Libraries](https://www.akkadia.org/drepper/dsohowto.pdf) +- [Dynamic Linker](https://wiki.osdev.org/Dynamic_Linker) +- [Nightingale OS](https://github.com/tyler569/nightingale) +- [PLT and GOT: The Key to Code Sharing and Dynamic Libraries](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html) +- [YouTube Video on Dynamic Linking](https://www.youtube.com/watch?v=kUk5pw4w0h4) +- [Oracle: Position Independent Code](https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html) +- [PLT and GOT Explained](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got) + +## Inter-Process Communication (IPC) +- [Oracle IPC](https://docs.oracle.com/cd/E19048-01/chorus5/806-6897/architecture-103/index.html) +- [Inter-Process Communication in OS](https://www.scaler.com/topics/operating-system/inter-process-communication-in-os/) +- [IPC on Wikipedia](https://en.wikipedia.org/wiki/Inter-process_communication) +- [GeeksforGeeks IPC Guide](https://www.geeksforgeeks.org/inter-process-communication-ipc/) + +## PCI (Peripheral Component Interconnect) +- [OSDev PCI](https://wiki.osdev.org/PCI) +- [PCI Configuration Space](https://en.wikipedia.org/wiki/PCI_configuration_space) + +## Audio +- [FFmpeg Audio Types](https://trac.ffmpeg.org/wiki/audio%20types) +- [AC97 on OSDev](https://wiki.osdev.org/AC97) +- [LemonOS Project](https://github.com/LemonOSProject/LemonOS) +- [AC97 Revision 2.3 Specification](https://inst.eecs.berkeley.edu//~cs150/Documents/ac97_r23.pdf) + +## Intrinsics (x86) +- [Microsoft x86 Intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/x86-intrinsics-list) +- [Intel Intrinsics Guide](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html) + +## CPUID Information +- [AMD CPUID Instruction](https://www.amd.com/system/files/TechDocs/40332.pdf) +- [CPUID Instruction Note](https://www.scss.tcd.ie/~jones/CS4021/processor-identification-cpuid-instruction-note.pdf) + +## SMBIOS (System Management BIOS) +- [DMTF DSP0134](https://www.dmtf.org/dsp/DSP0134) +- [DSP0134 Version 3.6.0](https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf) +- [OSDev SMBIOS](https://wiki.osdev.org/System_Management_BIOS) + +## EDBA (Effective Direct Bus Access) +- [Memory Map (x86)](https://wiki.osdev.org/Memory_Map_(x86)) + +## UMIP, SMAP, and SMEP +- [Control Register on Wikipedia](https://en.wikipedia.org/wiki/Control_register) +- [Control Register and UMIP](https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf) +- [Supervisor Mode Access Prevention (SMEP)](https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention) + +## Atomic Operations +- [C++ Atomic Operations](https://en.cppreference.com/w/cpp/atomic/atomic) + +## ELF (Executable and Linkable Format) +- [ELF Header Format](https://www.sco.com/developers/gabi/latest/ch4.eheader.html) +- [ELF File Format Specification](https://refspecs.linuxfoundation.org/elf/elf.pdf) +- [Oracle: Executable and Linkable Format](https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html) +- [Oracle: ELF Program Headers](https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html) +- [YouTube Video on ELF](https://www.youtube.com/watch?v=nC1U1LJQL8o) +- [Stevens' UNIX Network Programming](https://stevens.netmeister.org/631/elf.html) +- [Linux Kernel ELF Header](https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h) + +## C++ ABI (Application Binary Interface) +- [GCC libstdc++ Source](https://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3) +- [Itanium C++ ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi.html) + +## Keyboard +- [Scan Codes](https://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html) +- [PS/2 Keyboard on OSDev](https://wiki.osdev.org/PS/2_Keyboard) + +## signal.h +- [POSIX signal.h](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html) +- [Linux signal(7) Manual](https://man7.org/linux/man-pages/man7/signal.7.html) + +--- + +Special thanks to all contributors and the creators of the referenced projects and resources! diff --git a/Core/Crash/Screens/Console.cpp b/Core/Crash/Screens/Console.cpp deleted file mode 100644 index 44da0909..00000000 --- a/Core/Crash/Screens/Console.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../../crashhandler.hpp" -#include "../chfcts.hpp" - -#include -#include -#include -#include -#include - -#if defined(a64) -#include "../../../Architecture/amd64/cpu/gdt.hpp" -#elif defined(a32) -#elif defined(aa64) -#endif - -#include "../../../kernel.h" - -namespace CrashHandler -{ - SafeFunction void DisplayConsoleScreen(CRData data) - { - EHPrint("TODO"); - UNUSED(data); - } -} \ No newline at end of file diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp deleted file mode 100644 index 5a070f41..00000000 --- a/Core/Crash/UserHandler.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../crashhandler.hpp" -#include "chfcts.hpp" - -#include -#include -#include -#include -#include - -#if defined(a64) -#include "../../Architecture/amd64/cpu/gdt.hpp" -#elif defined(a32) -#elif defined(aa64) -#endif - -#include "../../kernel.h" - -static const char *PageFaultDescriptions[8] = { - "Supervisory process tried to read a non-present page entry\n", - "Supervisory process tried to read a page and caused a protection fault\n", - "Supervisory process tried to write to a non-present page entry\n", - "Supervisory process tried to write a page and caused a protection fault\n", - "User process tried to read a non-present page entry\n", - "User process tried to read a page and caused a protection fault\n", - "User process tried to write to a non-present page entry\n", - "User process tried to write a page and caused a protection fault\n"}; - -SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) -{ - CriticalSection cs; - debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No"); - fixme("Handling user mode exception"); - thisThread->Status = Tasking::TaskStatus::Zombie; - CPUData *CurCPU = GetCurrentCPU(); - - { -#if defined(a64) - CPU::x64::CR0 cr0 = CPU::x64::readcr0(); - CPU::x64::CR2 cr2 = CPU::x64::CR2{.PFLA = CrashHandler::PageFaultAddress}; - CPU::x64::CR3 cr3 = CPU::x64::readcr3(); - CPU::x64::CR4 cr4 = CPU::x64::readcr4(); - CPU::x64::CR8 cr8 = CPU::x64::readcr8(); - CPU::x64::EFER efer; - efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); - - error("Technical Informations on CPU %lld:", CurCPU->ID); - uintptr_t ds; - asmv("mov %%ds, %0" - : "=r"(ds)); -#elif defined(a32) - CPU::x32::CR0 cr0 = CPU::x32::readcr0(); - CPU::x32::CR2 cr2 = CPU::x32::CR2{.PFLA = CrashHandler::PageFaultAddress}; - CPU::x32::CR3 cr3 = CPU::x32::readcr3(); - CPU::x32::CR4 cr4 = CPU::x32::readcr4(); - CPU::x32::CR8 cr8 = CPU::x32::readcr8(); - - error("Technical Informations on CPU %lld:", CurCPU->ID); - uintptr_t ds; - asmv("mov %%ds, %0" - : "=r"(ds)); -#elif defined(aa64) -#endif - -#if defined(a64) - error("FS=%#lx GS=%#lx SS=%#lx CS=%#lx DS=%#lx", - CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), - Frame->ss, Frame->cs, ds); - error("R8=%#lx R9=%#lx R10=%#lx R11=%#lx", Frame->r8, Frame->r9, Frame->r10, Frame->r11); - error("R12=%#lx R13=%#lx R14=%#lx R15=%#lx", Frame->r12, Frame->r13, Frame->r14, Frame->r15); - error("RAX=%#lx RBX=%#lx RCX=%#lx RDX=%#lx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); - error("RSI=%#lx RDI=%#lx RBP=%#lx RSP=%#lx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); - error("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx EFER=%#lx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); -#elif defined(a32) - error("FS=%#x GS=%#x CS=%#x DS=%#x", - CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), - Frame->cs, ds); - error("EAX=%#x EBX=%#x ECX=%#x EDX=%#x", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); - error("ESI=%#x EDI=%#x EBP=%#x ESP=%#x", Frame->esi, Frame->edi, Frame->ebp, Frame->esp); - error("EIP=%#x EFL=%#x INT=%#x ERR=%#x", Frame->eip, Frame->eflags.raw, Frame->InterruptNumber, Frame->ErrorCode); -#elif defined(aa64) -#endif - -#if defined(a86) - error("CR0=%#lx CR2=%#lx CR3=%#lx CR4=%#lx CR8=%#lx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); - - error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", - cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", - cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False", - cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", - cr0.Reserved0, cr0.Reserved1, cr0.Reserved2); - - error("CR2: PFLA: %#lx", - cr2.PFLA); - - error("CR3: PWT:%s PCD:%s PDBR:%#llx", - cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); -#endif // defined(a86) - -#if defined(a64) - error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", - cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", - cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", - cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", - cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", - cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", - cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); -#elif defined(a32) - error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x", - cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", - cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", - cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", - cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", - cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", - cr4.Reserved0, cr4.Reserved1); -#endif - -#if defined(a86) - error("CR8: TPL:%d", cr8.TPL); -#endif // defined(a86) - -#if defined(a64) - error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", - Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", - Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", - Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", - Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", - Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, - Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); -#elif defined(a32) - error("EFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x", - Frame->eflags.CF ? "True " : "False", Frame->eflags.PF ? "True " : "False", Frame->eflags.AF ? "True " : "False", Frame->eflags.ZF ? "True " : "False", - Frame->eflags.SF ? "True " : "False", Frame->eflags.TF ? "True " : "False", Frame->eflags.IF ? "True " : "False", Frame->eflags.DF ? "True " : "False", - Frame->eflags.OF ? "True " : "False", Frame->eflags.IOPL ? "True " : "False", Frame->eflags.NT ? "True " : "False", Frame->eflags.RF ? "True " : "False", - Frame->eflags.VM ? "True " : "False", Frame->eflags.AC ? "True " : "False", Frame->eflags.VIF ? "True " : "False", Frame->eflags.VIP ? "True " : "False", - Frame->eflags.ID ? "True " : "False", Frame->eflags.AlwaysOne, - Frame->eflags.Reserved0, Frame->eflags.Reserved1, Frame->eflags.Reserved2); -#elif defined(aa64) -#endif - -#if defined(a64) - error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", - efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", - efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", - efer.Reserved0, efer.Reserved1, efer.Reserved2); -#endif - } - - switch (Frame->InterruptNumber) - { - case CPU::x86::DivideByZero: - { - break; - } - case CPU::x86::Debug: - { - break; - } - case CPU::x86::NonMaskableInterrupt: - { - break; - } - case CPU::x86::Breakpoint: - { - break; - } - case CPU::x86::Overflow: - { - break; - } - case CPU::x86::BoundRange: - { - break; - } - case CPU::x86::InvalidOpcode: - { - break; - } - case CPU::x86::DeviceNotAvailable: - { - break; - } - case CPU::x86::DoubleFault: - { - break; - } - case CPU::x86::CoprocessorSegmentOverrun: - { - break; - } - case CPU::x86::InvalidTSS: - { - break; - } - case CPU::x86::SegmentNotPresent: - { - break; - } - case CPU::x86::StackSegmentFault: - { - break; - } - case CPU::x86::GeneralProtectionFault: - { - break; - } - case CPU::x86::PageFault: - { - uintptr_t CheckPageFaultAddress = 0; - CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; -#if defined(a64) - CheckPageFaultAddress = CrashHandler::PageFaultAddress; - if (CheckPageFaultAddress == 0) - CheckPageFaultAddress = Frame->rip; - - error("An exception occurred at %#lx by %#lx", CrashHandler::PageFaultAddress, Frame->rip); -#elif defined(a32) - CheckPageFaultAddress = CrashHandler::PageFaultAddress; - if (CheckPageFaultAddress == 0) - CheckPageFaultAddress = Frame->eip; - - error("An exception occurred at %#lx by %#lx", CrashHandler::PageFaultAddress, Frame->eip); -#elif defined(aa64) -#endif - error("Page: %s", params.P ? "Present" : "Not Present"); - error("Write Operation: %s", params.W ? "Read-Only" : "Read-Write"); - error("Processor Mode: %s", params.U ? "User-Mode" : "Kernel-Mode"); - error("CPU Reserved Bits: %s", params.R ? "Reserved" : "Unreserved"); - error("Caused By An Instruction Fetch: %s", params.I ? "Yes" : "No"); - error("Caused By A Protection-Key Violation: %s", params.PK ? "Yes" : "No"); - error("Caused By A Shadow Stack Access: %s", params.SS ? "Yes" : "No"); - error("Caused By An SGX Violation: %s", params.SGX ? "Yes" : "No"); - if (Frame->ErrorCode & 0x00000008) - error("One or more page directory entries contain reserved bits which are set to 1."); - else - error(PageFaultDescriptions[Frame->ErrorCode & 0b111]); - -#ifdef DEBUG - if (CurCPU) - { - Memory::Virtual vmm = Memory::Virtual(CurCPU->CurrentProcess->PageTable); - bool PageAvailable = vmm.Check((void *)CheckPageFaultAddress); - debug("Page available (Check(...)): %s. %s", - PageAvailable ? "Yes" : "No", - (params.P && !PageAvailable) ? "CR2 == Present; Check() != Present??????" : "CR2 confirms Check() result."); - - if (PageAvailable) - { - bool Present = vmm.Check((void *)CheckPageFaultAddress); - bool ReadWrite = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::RW); - bool User = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::US); - bool WriteThrough = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::PWT); - bool CacheDisabled = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::PCD); - bool Accessed = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::A); - bool Dirty = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::D); - bool Global = vmm.Check((void *)CheckPageFaultAddress, Memory::PTFlag::G); - /* ... */ - - debug("Page available: %s", Present ? "Yes" : "No"); - debug("Page read/write: %s", ReadWrite ? "Yes" : "No"); - debug("Page user/kernel: %s", User ? "User" : "Kernel"); - debug("Page write-through: %s", WriteThrough ? "Yes" : "No"); - debug("Page cache disabled: %s", CacheDisabled ? "Yes" : "No"); - debug("Page accessed: %s", Accessed ? "Yes" : "No"); - debug("Page dirty: %s", Dirty ? "Yes" : "No"); - debug("Page global: %s", Global ? "Yes" : "No"); - - if (Present) - { -#if defined(a64) - uintptr_t CheckPageFaultLinearAddress = (uintptr_t)CheckPageFaultAddress; - CheckPageFaultLinearAddress &= 0xFFFFFFFFFFFFF000; - debug("%#lx -> %#lx", CheckPageFaultAddress, CheckPageFaultLinearAddress); - - Memory::Virtual::PageMapIndexer Index = Memory::Virtual::PageMapIndexer((uintptr_t)CheckPageFaultLinearAddress); - debug("Index for %#lx is PML:%d PDPTE:%d PDE:%d PTE:%d", - CheckPageFaultLinearAddress, - Index.PMLIndex, - Index.PDPTEIndex, - Index.PDEIndex, - Index.PTEIndex); - Memory::PageMapLevel4 PML4 = CurCPU->CurrentProcess->PageTable->Entries[Index.PMLIndex]; - - Memory::PageDirectoryPointerTableEntryPtr *PDPTE = (Memory::PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12); - Memory::PageDirectoryEntryPtr *PDE = (Memory::PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12); - Memory::PageTableEntryPtr *PTE = (Memory::PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12); - - debug("# %03d-%03d-%03d-%03d: P:%s RW:%s US:%s PWT:%s PCB:%s A:%s NX:%s Address:%#lx", - Index.PMLIndex, 0, 0, 0, - PML4.Present ? "1" : "0", - PML4.ReadWrite ? "1" : "0", - PML4.UserSupervisor ? "1" : "0", - PML4.WriteThrough ? "1" : "0", - PML4.CacheDisable ? "1" : "0", - PML4.Accessed ? "1" : "0", - PML4.ExecuteDisable ? "1" : "0", - PML4.GetAddress() << 12); - - debug("# %03d-%03d-%03d-%03d: P:%s RW:%s US:%s PWT:%s PCB:%s A:%s NX:%s Address:%#lx", - Index.PMLIndex, Index.PDPTEIndex, 0, 0, - PDPTE->Entries[Index.PDPTEIndex].Present ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].ReadWrite ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].UserSupervisor ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].WriteThrough ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].CacheDisable ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].Accessed ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].ExecuteDisable ? "1" : "0", - PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12); - - debug("# %03d-%03d-%03d-%03d: P:%s RW:%s US:%s PWT:%s PCB:%s A:%s NX:%s Address:%#lx", - Index.PMLIndex, Index.PDPTEIndex, Index.PDEIndex, 0, - PDE->Entries[Index.PDEIndex].Present ? "1" : "0", - PDE->Entries[Index.PDEIndex].ReadWrite ? "1" : "0", - PDE->Entries[Index.PDEIndex].UserSupervisor ? "1" : "0", - PDE->Entries[Index.PDEIndex].WriteThrough ? "1" : "0", - PDE->Entries[Index.PDEIndex].CacheDisable ? "1" : "0", - PDE->Entries[Index.PDEIndex].Accessed ? "1" : "0", - PDE->Entries[Index.PDEIndex].ExecuteDisable ? "1" : "0", - PDE->Entries[Index.PDEIndex].GetAddress() << 12); - - debug("# %03d-%03d-%03d-%03d: P:%s RW:%s US:%s PWT:%s PCB:%s A:%s D:%s PAT:%s G:%s PK:%d NX:%s Address:%#lx", - Index.PMLIndex, Index.PDPTEIndex, Index.PDEIndex, Index.PTEIndex, - PTE->Entries[Index.PTEIndex].Present ? "1" : "0", - PTE->Entries[Index.PTEIndex].ReadWrite ? "1" : "0", - PTE->Entries[Index.PTEIndex].UserSupervisor ? "1" : "0", - PTE->Entries[Index.PTEIndex].WriteThrough ? "1" : "0", - PTE->Entries[Index.PTEIndex].CacheDisable ? "1" : "0", - PTE->Entries[Index.PTEIndex].Accessed ? "1" : "0", - PTE->Entries[Index.PTEIndex].Dirty ? "1" : "0", - PTE->Entries[Index.PTEIndex].PageAttributeTable ? "1" : "0", - PTE->Entries[Index.PTEIndex].Global ? "1" : "0", - PTE->Entries[Index.PTEIndex].ProtectionKey, - PTE->Entries[Index.PTEIndex].ExecuteDisable ? "1" : "0", - PTE->Entries[Index.PTEIndex].GetAddress() << 12); -#endif - } - } - } -#endif - - if (CurCPU) - if (CurCPU->CurrentThread->Stack->Expand(CrashHandler::PageFaultAddress)) - { - debug("Stack expanded"); - thisThread->Status = Tasking::TaskStatus::Ready; - return; - } - break; - } - case CPU::x86::x87FloatingPoint: - { - break; - } - case CPU::x86::AlignmentCheck: - { - break; - } - case CPU::x86::MachineCheck: - { - break; - } - case CPU::x86::SIMDFloatingPoint: - { - break; - } - case CPU::x86::Virtualization: - { - break; - } - case CPU::x86::Security: - { - break; - } - default: - { - break; - } - } - - thisThread->Status = Tasking::TaskStatus::Terminated; - __sync; - error("End of report."); - CPU::Interrupts(CPU::Enable); - debug("Interrupts enabled back."); - return; -} diff --git a/Core/Disk.cpp b/Core/Disk.cpp deleted file mode 100644 index 5aa3ddb6..00000000 --- a/Core/Disk.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -#include "../kernel.h" -#include "../DAPI.hpp" -#include "../Fex.hpp" - -namespace Disk -{ - void Manager::FetchDisks(unsigned long DriverUID) - { - KernelCallback callback{}; - callback.Reason = QueryReason; - DriverManager->IOCB(DriverUID, &callback); - this->AvailablePorts = callback.DiskCallback.Fetch.Ports; - this->BytesPerSector = callback.DiskCallback.Fetch.BytesPerSector; - debug("AvailablePorts:%ld BytesPerSector:%ld", this->AvailablePorts, this->BytesPerSector); - - if (this->AvailablePorts <= 0) - return; - - uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector + 1)); - - for (unsigned char ItrPort = 0; ItrPort < this->AvailablePorts; ItrPort++) - { - Drive drive{}; - sprintf(drive.Name, "sd%ld", DriverUID); - debug("Drive Name: %s", drive.Name); - // TODO: Implement disk type detection. Very useful in the future. - drive.MechanicalDisk = true; - - memset(RWBuffer, 0, this->BytesPerSector); - callback.Reason = ReceiveReason; - callback.DiskCallback.RW = { - .Sector = 0, - .SectorCount = 2, - .Port = ItrPort, - .Buffer = RWBuffer, - .Write = false, - }; - DriverManager->IOCB(DriverUID, &callback); - memcpy(&drive.Table, RWBuffer, sizeof(PartitionTable)); - - /* - TODO: Add to devfs the disk - */ - - if (drive.Table.GPT.Signature == GPT_MAGIC) - { - drive.Style = GPT; - uint32_t Entries = 512 / drive.Table.GPT.EntrySize; - uint32_t Sectors = drive.Table.GPT.PartCount / Entries; - for (uint32_t Block = 0; Block < Sectors; Block++) - { - memset(RWBuffer, 0, this->BytesPerSector); - callback.Reason = ReceiveReason; - callback.DiskCallback.RW = { - .Sector = 2 + Block, - .SectorCount = 1, - .Port = ItrPort, - .Buffer = RWBuffer, - .Write = false, - }; - DriverManager->IOCB(DriverUID, &callback); - - for (uint32_t e = 0; e < Entries; e++) - { - GUIDPartitionTableEntry GPTPartition = reinterpret_cast(RWBuffer)[e]; - if (memcmp(GPTPartition.PartitionType, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(GPTPartition.PartitionType)) != 0) - { - debug("Partition Type: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - GPTPartition.PartitionType[0], GPTPartition.PartitionType[1], GPTPartition.PartitionType[2], GPTPartition.PartitionType[3], - GPTPartition.PartitionType[4], GPTPartition.PartitionType[5], GPTPartition.PartitionType[6], GPTPartition.PartitionType[7], - GPTPartition.PartitionType[8], GPTPartition.PartitionType[9], GPTPartition.PartitionType[10], GPTPartition.PartitionType[11], - GPTPartition.PartitionType[12], GPTPartition.PartitionType[13], GPTPartition.PartitionType[14], GPTPartition.PartitionType[15]); - - debug("Unique Partition GUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - GPTPartition.UniquePartitionGUID[0], GPTPartition.UniquePartitionGUID[1], GPTPartition.UniquePartitionGUID[2], GPTPartition.UniquePartitionGUID[3], - GPTPartition.UniquePartitionGUID[4], GPTPartition.UniquePartitionGUID[5], GPTPartition.UniquePartitionGUID[6], GPTPartition.UniquePartitionGUID[7], - GPTPartition.UniquePartitionGUID[8], GPTPartition.UniquePartitionGUID[9], GPTPartition.UniquePartitionGUID[10], GPTPartition.UniquePartitionGUID[11], - GPTPartition.UniquePartitionGUID[12], GPTPartition.UniquePartitionGUID[13], GPTPartition.UniquePartitionGUID[14], GPTPartition.UniquePartitionGUID[15]); - - Partition partition{}; - memset(partition.Label, '\0', sizeof(partition.Label)); - /* Convert utf16 to utf8 */ - for (int i = 0; i < 36; i++) - { - uint16_t utf16 = GPTPartition.PartitionName[i]; - if (utf16 == 0) - break; - if (utf16 < 0x80) - partition.Label[i] = (char)utf16; - else if (utf16 < 0x800) - { - partition.Label[i] = (char)(0xC0 | (utf16 >> 6)); - partition.Label[i + 1] = (char)(0x80 | (utf16 & 0x3F)); - i++; - } - else - { - partition.Label[i] = (char)(0xE0 | (utf16 >> 12)); - partition.Label[i + 1] = (char)(0x80 | ((utf16 >> 6) & 0x3F)); - partition.Label[i + 2] = (char)(0x80 | (utf16 & 0x3F)); - i += 2; - } - } - partition.StartLBA = GPTPartition.FirstLBA; - partition.EndLBA = GPTPartition.LastLBA; - partition.Sectors = (size_t)(partition.EndLBA - partition.StartLBA); - partition.Port = ItrPort; - partition.Flags = Present; - partition.Style = GPT; - if (GPTPartition.Attributes & 1) - partition.Flags |= EFISystemPartition; - partition.Index = drive.Partitions.size(); - trace("GPT partition \"%s\" found with %lld sectors", partition.Label, partition.Sectors); - drive.Partitions.push_back(partition); - - char PartitionName[64]; - sprintf(PartitionName, "sd%ldp%ld", drives.size(), partition.Index); - fixme("PartitionName: %s", PartitionName); - - /* - TODO: Add to devfs the disk - */ - } - } - } - trace("%d GPT partitions found.", drive.Partitions.size()); - } - else if (drive.Table.MBR.Signature[0] == MBR_MAGIC0 && drive.Table.MBR.Signature[1] == MBR_MAGIC1) - { - drive.Style = MBR; - for (size_t p = 0; p < 4; p++) - if (drive.Table.MBR.Partitions[p].LBAFirst != 0) - { - Partition partition{}; - partition.StartLBA = drive.Table.MBR.Partitions[p].LBAFirst; - partition.EndLBA = drive.Table.MBR.Partitions[p].LBAFirst + drive.Table.MBR.Partitions[p].Sectors; - partition.Sectors = drive.Table.MBR.Partitions[p].Sectors; - partition.Port = ItrPort; - partition.Flags = Present; - partition.Style = MBR; - partition.Index = drive.Partitions.size(); - trace("Partition \"%#llx\" found with %lld sectors.", drive.Table.MBR.UniqueID, partition.Sectors); - drive.Partitions.push_back(partition); - - char PartitionName[64]; - sprintf(PartitionName, "sd%ldp%ld", drives.size(), partition.Index); - fixme("PartitionName: %s", PartitionName); - - /* - TODO: Add to devfs the disk - */ - } - trace("%d MBR partitions found.", drive.Partitions.size()); - } - else - warn("No partition table found on port %d!", ItrPort); - - drives.push_back(drive); - } - - KernelAllocator.FreePages(RWBuffer, TO_PAGES(this->BytesPerSector + 1)); - } - - Manager::Manager() - { - } - - Manager::~Manager() - { - debug("Destructor called"); - } -} diff --git a/Core/Driver/Driver.cpp b/Core/Driver/Driver.cpp deleted file mode 100644 index 280dace5..00000000 --- a/Core/Driver/Driver.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include -#include -#include -#include -#include - -#include "../../Modules/drv.hpp" -#include "../../kernel.h" -#include "../../DAPI.hpp" -#include "../../Fex.hpp" -#include "api.hpp" - -namespace Driver -{ - void Driver::Panic() - { - debug("%ld drivers loaded, [DriverUIDs: %ld]", Drivers.size(), DriverUIDs - 1); - - foreach (auto Drv in Drivers) - { - KernelCallback callback{}; - callback.Reason = StopReason; - DriverManager->IOCB(Drv.DriverUID, &callback); - - for (size_t j = 0; j < sizeof(Drv.InterruptHook) / sizeof(Drv.InterruptHook[0]); j++) - { - if (!Drv.InterruptHook[j]) - continue; - - Drv.InterruptHook[j]->Disable(); - debug("Interrupt hook %#lx disabled", Drv.InterruptHook[j]); - } - } - } - - void Driver::UnloadAllDrivers() - { - debug("%ld drivers loaded, [DriverUIDs: %ld]", Drivers.size(), DriverUIDs - 1); - - foreach (auto Drv in Drivers) - { - KernelCallback callback{}; - callback.Reason = StopReason; - debug("Stopping & unloading driver %ld [%#lx]", Drv.DriverUID, Drv.Address); - DriverManager->IOCB(Drv.DriverUID, &callback); - - for (size_t j = 0; j < sizeof(Drv.InterruptHook) / sizeof(Drv.InterruptHook[0]); j++) - { - if (!Drv.InterruptHook[j]) - continue; - - debug("Interrupt hook %#lx", Drv.InterruptHook[j]); - delete Drv.InterruptHook[j], Drv.InterruptHook[j] = nullptr; - } - - if (Drv.MemTrk) - delete Drv.MemTrk, Drv.MemTrk = nullptr; - } - Drivers.clear(); - } - - bool Driver::UnloadDriver(unsigned long DUID) - { - debug("Searching for driver %ld", DUID); - - forItr(Drv, Drivers) - { - if (Drv->DriverUID != DUID) - continue; - - KernelCallback callback{}; - callback.Reason = StopReason; - debug("Stopping & unloading driver %ld [%#lx]", Drv->DriverUID, Drv->Address); - this->IOCB(Drv->DriverUID, &callback); - - for (size_t j = 0; j < sizeof(Drv->InterruptHook) / sizeof(Drv->InterruptHook[0]); j++) - { - if (!Drv->InterruptHook[j]) - continue; - - debug("Interrupt hook %#lx", Drv->InterruptHook[j]); - delete Drv->InterruptHook[j], Drv->InterruptHook[j] = nullptr; - } - - if (Drv->MemTrk) - delete Drv->MemTrk, Drv->MemTrk = nullptr; - - Drivers.erase(Drv); - return true; - } - return false; - } - - int Driver::IOCB(unsigned long DUID, void *KCB) - { - foreach (auto Drv in Drivers) - { - if (Drv.DriverUID != DUID) - continue; - - FexExtended *fexE = (FexExtended *)Drv.ExtendedHeaderAddress; - return ((int (*)(void *))((uintptr_t)fexE->Driver.Callback + (uintptr_t)Drv.Address))(KCB); - } - return -1; - } - - DriverCode Driver::CallDriverEntryPoint(void *fex, bool BuiltIn) - { - DriverCode ret{}; - KernelAPI DriverKAPI = KernelAPITemplate; - - DriverKAPI.Info.DriverUID = DriverUIDs++; - DriverKAPI.Info.KernelDebug = DebuggerIsAttached; - - debug("Calling driver entry point ( %#lx %ld )", (unsigned long)fex, DriverKAPI.Info.DriverUID); - - if (!BuiltIn) - { - DriverKAPI.Info.Offset = (unsigned long)fex; - - debug("DRIVER: %s HAS DRIVER ID %ld", - ((FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS))->Driver.Name, - DriverKAPI.Info.DriverUID); - ret = ((DriverCode(*)(KernelAPI *))((uintptr_t)((Fex *)fex)->EntryPoint + (uintptr_t)fex))(((KernelAPI *)&DriverKAPI)); - } - else - { - debug("DRIVER: BUILTIN HAS DRIVER ID %ld", DriverKAPI.Info.DriverUID); - ret = ((DriverCode(*)(KernelAPI *))((uintptr_t)fex))(((KernelAPI *)&DriverKAPI)); - } - - if (DriverCode::OK != ret) - { - DriverUIDs--; - return ret; - } - return DriverCode::OK; - } - - DriverCode Driver::LoadDriver(uintptr_t DriverAddress, size_t Size) - { - Fex *DrvHdr = (Fex *)DriverAddress; - if (DrvHdr->Magic[0] != 'F' || DrvHdr->Magic[1] != 'E' || DrvHdr->Magic[2] != 'X' || DrvHdr->Magic[3] != '\0') - return DriverCode::INVALID_FEX_HEADER; - - debug("Fex Magic: \"%s\"; Type: %d; OS: %d; EntryPoint: %#lx", DrvHdr->Magic, DrvHdr->Type, DrvHdr->OS, DrvHdr->EntryPoint); - - if (DrvHdr->Type != FexFormatType::FexFormatType_Driver) - return DriverCode::NOT_DRIVER; - - FexExtended *fexE = (FexExtended *)((uintptr_t)DrvHdr + EXTENDED_SECTION_ADDRESS); - debug("Name: \"%s\"; Type: %d; Callback: %#lx", fexE->Driver.Name, fexE->Driver.Type, fexE->Driver.Callback); - - switch (fexE->Driver.Bind.Type) - { - case DriverBindType::BIND_PCI: - return this->DriverLoadBindPCI(DriverAddress, Size); - case DriverBindType::BIND_INTERRUPT: - return this->DriverLoadBindInterrupt(DriverAddress, Size); - case DriverBindType::BIND_PROCESS: - return this->DriverLoadBindProcess(DriverAddress, Size); - case DriverBindType::BIND_INPUT: - return this->DriverLoadBindInput(DriverAddress, Size); - default: - { - error("Unknown driver bind type: %d", fexE->Driver.Bind.Type); - return DriverCode::UNKNOWN_DRIVER_BIND_TYPE; - } - } - } - - void Driver::LoadDrivers() - { - SmartCriticalSection(DriverInitLock); - - std::string DriverConfigFile = Config.DriverDirectory; - DriverConfigFile << "/config.ini"; - fixme("Loading driver config file: %s", DriverConfigFile.c_str()); - - debug("Loading built-in drivers"); - StartAHCI(); - StartVMwareMouse(); - StartPS2Mouse(); - StartPS2Keyboard(); - StartATA(); - StartAC97(); - StartRTL8139(); - StartPCNET(); - StartGigabit(); - - RefNode *DriverDirectory = vfs->Open(Config.DriverDirectory); - if (!DriverDirectory) - { - KPrint("\eE85230Failed to open %s: %d)", - Config.DriverDirectory, errno); - return; - } - - debug("Loading drivers from %s", Config.DriverDirectory); - foreach (auto DrvFile in DriverDirectory->GetNode()->Children) - { - if (DrvFile->Flags != VirtualFileSystem::NodeFlags::FILE) - continue; - - if (cwk_path_has_extension(DrvFile->Name)) - { - const char *extension; - size_t extension_length; - cwk_path_get_extension(DrvFile->Name, &extension, &extension_length); - debug("File: %s; Extension: %s", DrvFile->Name, extension); - if (strcmp(extension, ".fex") == 0) - { - uintptr_t ret = this->LoadDriver(DrvFile->Address, DrvFile->Length); - std::string RetString; - if (ret == DriverCode::OK) - RetString << "\e058C19OK"; - else if (ret == DriverCode::NOT_AVAILABLE) - RetString << "\eFF7900NOT AVAILABLE"; - else - RetString << "\eE85230FAILED"; - KPrint("%s %s %#lx", DrvFile->Name, RetString.c_str(), ret); - } - } - } - delete DriverDirectory; - } - - Driver::Driver() {} - - Driver::~Driver() - { - debug("Destructor called"); - this->UnloadAllDrivers(); - } - -#if defined(a64) - SafeFunction void DriverInterruptHook::OnInterruptReceived(CPU::x64::TrapFrame *Frame) -#elif defined(a32) - SafeFunction void DriverInterruptHook::OnInterruptReceived(CPU::x32::TrapFrame *Frame) -#elif defined(aa64) - SafeFunction void DriverInterruptHook::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) -#endif - { - SmartLock(DriverInterruptLock); /* Lock in case of multiple interrupts firing at the same time */ - if (!this->Enabled) - { - debug("Interrupt hook is not enabled"); - return; - } - - if (!Handle.InterruptCallback) - { -#if defined(a86) - uint64_t IntNum = Frame->InterruptNumber - 32; -#elif defined(aa64) - uint64_t IntNum = Frame->InterruptNumber; -#endif - warn("Interrupt callback for %ld is not set for driver %ld!", IntNum, Handle.DriverUID); - return; - } - CPURegisters regs; -#if defined(a64) - regs.r15 = Frame->r15; - regs.r14 = Frame->r14; - regs.r13 = Frame->r13; - regs.r12 = Frame->r12; - regs.r11 = Frame->r11; - regs.r10 = Frame->r10; - regs.r9 = Frame->r9; - regs.r8 = Frame->r8; - - regs.rbp = Frame->rbp; - regs.rdi = Frame->rdi; - regs.rsi = Frame->rsi; - regs.rdx = Frame->rdx; - regs.rcx = Frame->rcx; - regs.rbx = Frame->rbx; - regs.rax = Frame->rax; - - regs.InterruptNumber = Frame->InterruptNumber; - regs.ErrorCode = Frame->ErrorCode; - regs.rip = Frame->rip; - regs.cs = Frame->cs; - regs.rflags = Frame->rflags.raw; - regs.rsp = Frame->rsp; - regs.ss = Frame->ss; -#elif defined(a32) - regs.edi = Frame->edi; - regs.esi = Frame->esi; - regs.ebp = Frame->ebp; - regs.esp = Frame->esp; - regs.ebx = Frame->ebx; - regs.edx = Frame->edx; - regs.ecx = Frame->ecx; - regs.eax = Frame->eax; - - regs.InterruptNumber = Frame->InterruptNumber; - regs.ErrorCode = Frame->ErrorCode; - regs.eip = Frame->eip; - regs.cs = Frame->cs; - regs.eflags = Frame->eflags.raw; - regs.r3_esp = Frame->r3_esp; - regs.r3_ss = Frame->r3_ss; -#elif defined(aa64) -#endif - ((int (*)(void *))(Handle.InterruptCallback))(®s); - UNUSED(Frame); - } - - DriverInterruptHook::DriverInterruptHook(int Interrupt, DriverFile Handle) : Interrupts::Handler(Interrupt) - { - this->Handle = Handle; -#if defined(a86) - trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); -#elif defined(aa64) - trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); -#endif - } -} diff --git a/Core/Driver/DriverAPI.cpp b/Core/Driver/DriverAPI.cpp deleted file mode 100644 index 281391f9..00000000 --- a/Core/Driver/DriverAPI.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -#include "../../kernel.h" -#include "../../Fex.hpp" -#include "api.hpp" - -// show debug messages -// #define DEBUG_DRIVER_API 1 - -#ifdef DEBUG_DRIVER_API -#define drvdbg(m, ...) debug(m, ##__VA_ARGS__) -#else -#define drvdbg(m, ...) -#endif - -NewLock(DriverDisplayPrintLock); - -void DriverDebugPrint(char *String, __UINT64_TYPE__ DriverUID) -{ - trace("[%ld] %s", DriverUID, String); -} - -void DriverDisplayPrint(char *String) -{ - SmartLock(DriverDisplayPrintLock); - for (__UINT64_TYPE__ i = 0; i < strlen(String); i++) - Display->Print(String[i], 0, true); -} - -void *RequestPage(__UINT64_TYPE__ Size) -{ - void *ret = KernelAllocator.RequestPages(size_t(Size + 1)); - drvdbg("Allocated %ld pages (%#lx-%#lx)", - Size, (__UINT64_TYPE__)ret, - (__UINT64_TYPE__)ret + FROM_PAGES(Size)); - return ret; -} - -void FreePage(void *Page, __UINT64_TYPE__ Size) -{ - drvdbg("Freeing %ld pages (%#lx-%#lx)", - Size, (__UINT64_TYPE__)Page, - (__UINT64_TYPE__)Page + FROM_PAGES(Size)); - KernelAllocator.FreePages(Page, size_t(Size + 1)); -} - -void MapMemory(void *VirtualAddress, void *PhysicalAddress, __UINT64_TYPE__ Flags) -{ - SmartLock(DriverDisplayPrintLock); - drvdbg("Mapping %#lx to %#lx with flags %#lx...", - (__UINT64_TYPE__)VirtualAddress, - (__UINT64_TYPE__)PhysicalAddress, Flags); - Memory::Virtual(KernelPageTable).Map(VirtualAddress, PhysicalAddress, Flags); -} - -void UnmapMemory(void *VirtualAddress) -{ - SmartLock(DriverDisplayPrintLock); - drvdbg("Unmapping %#lx...", - (__UINT64_TYPE__)VirtualAddress); - Memory::Virtual(KernelPageTable).Unmap(VirtualAddress); -} - -void *Drivermemcpy(void *Destination, void *Source, __UINT64_TYPE__ Size) -{ - SmartLock(DriverDisplayPrintLock); - drvdbg("Copying %ld bytes from %#lx-%#lx to %#lx-%#lx...", Size, - (__UINT64_TYPE__)Source, (__UINT64_TYPE__)Source + Size, - (__UINT64_TYPE__)Destination, (__UINT64_TYPE__)Destination + Size); - return memcpy(Destination, Source, size_t(Size)); -} - -void *Drivermemset(void *Destination, int Value, __UINT64_TYPE__ Size) -{ - SmartLock(DriverDisplayPrintLock); - drvdbg("Setting value %#x at %#lx-%#lx (%ld bytes)...", Value, - (__UINT64_TYPE__)Destination, - (__UINT64_TYPE__)Destination + Size, Size); - return memset(Destination, Value, size_t(Size)); -} - -void DriverNetSend(__UINT32_TYPE__ DriverID, - __UINT8_TYPE__ *Data, - __UINT16_TYPE__ Size) -{ - // This is useless I guess... - if (NIManager) - NIManager->DrvSend(DriverID, Data, Size); -} - -void DriverNetReceive(__UINT32_TYPE__ DriverID, - __UINT8_TYPE__ *Data, - __UINT16_TYPE__ Size) -{ - if (NIManager) - NIManager->DrvReceive(DriverID, Data, Size); -} - -void DriverAHCIDiskRead(__UINT32_TYPE__ DriverID, - __UINT64_TYPE__ Sector, - __UINT8_TYPE__ *Data, - __UINT32_TYPE__ SectorCount, - __UINT8_TYPE__ Port) -{ - DumpData("DriverDiskRead", Data, SectorCount * 512); - UNUSED(DriverID); - UNUSED(Sector); - UNUSED(Port); -} - -void DriverAHCIDiskWrite(__UINT32_TYPE__ DriverID, - __UINT64_TYPE__ Sector, - __UINT8_TYPE__ *Data, - __UINT32_TYPE__ SectorCount, - __UINT8_TYPE__ Port) -{ - DumpData("DriverDiskWrite", - Data, SectorCount * 512); - UNUSED(DriverID); - UNUSED(Sector); - UNUSED(Port); -} - -char *DriverPCIGetDeviceName(__UINT32_TYPE__ VendorID, - __UINT32_TYPE__ DeviceID) -{ - UNUSED(VendorID); - UNUSED(DeviceID); - return (char *)"Unknown"; -} - -__UINT32_TYPE__ DriverGetWidth() -{ - /* TODO: We won't rely only on display buffers, - what about graphics drivers and changing resolutions? */ - return Display->GetBuffer(0)->Width; -} - -__UINT32_TYPE__ DriverGetHeight() -{ - /* TODO: We won't rely only on display buffers, - what about graphics drivers and changing resolutions? */ - return Display->GetBuffer(0)->Height; -} - -void DriverSleep(__UINT64_TYPE__ Milliseconds) -{ - SmartLock(DriverDisplayPrintLock); - drvdbg("Sleeping for %ld milliseconds...", Milliseconds); - if (TaskManager) - TaskManager->Sleep(Milliseconds); - else - TimeManager->Sleep(size_t(Milliseconds), - Time::Units::Milliseconds); -} - -int Driversprintf(char *Buffer, const char *Format, ...) -{ - va_list args; - va_start(args, Format); - int ret = vsprintf(Buffer, Format, args); - va_end(args); - return ret; -} - -KernelAPI KernelAPITemplate = { - .Version = { - .Major = 0, - .Minor = 0, - .Patch = 1}, - .Info = { - .Offset = 0, - .DriverUID = 0, - .KernelDebug = false, - }, - .Memory = { - .PageSize = PAGE_SIZE, - .RequestPage = RequestPage, - .FreePage = FreePage, - .Map = MapMemory, - .Unmap = UnmapMemory, - }, - .PCI = { - .GetDeviceName = DriverPCIGetDeviceName, - }, - .Util = { - .DebugPrint = DriverDebugPrint, - .DisplayPrint = DriverDisplayPrint, - .memcpy = Drivermemcpy, - .memset = Drivermemset, - .Sleep = DriverSleep, - .sprintf = Driversprintf, - }, - .Command = { - .Network = { - .SendPacket = DriverNetSend, - .ReceivePacket = DriverNetReceive, - }, - .Disk = { - .AHCI = { - .ReadSector = DriverAHCIDiskRead, - .WriteSector = DriverAHCIDiskWrite, - }, - }, - }, - .Display = { - .GetWidth = DriverGetWidth, - .GetHeight = DriverGetHeight, - }, -}; diff --git a/Core/Driver/DriverBinding/BindInput.cpp b/Core/Driver/DriverBinding/BindInput.cpp deleted file mode 100644 index 98fe0c95..00000000 --- a/Core/Driver/DriverBinding/BindInput.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../api.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include "../../../kernel.h" -#include "../../../DAPI.hpp" -#include "../../../Fex.hpp" - -namespace Driver -{ - DriverCode Driver::DriverLoadBindInput(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn) - { - stub; - UNUSED(DriverAddress); - UNUSED(Size); - UNUSED(IsBuiltIn); - return DriverCode::NOT_IMPLEMENTED; - } -} diff --git a/Core/Driver/DriverBinding/BindInterrupt.cpp b/Core/Driver/DriverBinding/BindInterrupt.cpp deleted file mode 100644 index 09cfdcfb..00000000 --- a/Core/Driver/DriverBinding/BindInterrupt.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../api.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include "../../../kernel.h" -#include "../../../DAPI.hpp" -#include "../../../Fex.hpp" - -namespace Driver -{ - DriverCode Driver::DriverLoadBindInterrupt(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn) - { - Memory::MemMgr *mem = new Memory::MemMgr(nullptr, thisProcess->memDirectory); - - BuiltInDriverInfo *bidi = (BuiltInDriverInfo *)DriverAddress; - Fex *fex = nullptr; - if (!IsBuiltIn) - { - fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1)); - memcpy(fex, (void *)DriverAddress, Size); - debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); - } - else - fex = (Fex *)bidi->EntryPoint; - DriverCode ret = CallDriverEntryPoint(fex, IsBuiltIn); - if (ret != DriverCode::OK) - { - delete mem; - return ret; - } - - if (IsBuiltIn) - fex = 0x0; /* Addresses are absolute if built-in. */ - - FexExtended *fexE = IsBuiltIn ? (FexExtended *)bidi->ExtendedHeader : (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); - - debug("Starting driver %s", fexE->Driver.Name); - - switch (fexE->Driver.Type) - { - case FexDriverType::FexDriverType_Generic: - case FexDriverType::FexDriverType_Display: - case FexDriverType::FexDriverType_Network: - case FexDriverType::FexDriverType_Storage: - case FexDriverType::FexDriverType_FileSystem: - case FexDriverType::FexDriverType_Input: - case FexDriverType::FexDriverType_Audio: - { - FexExtended *DriverExtendedHeader = (FexExtended *)mem->RequestPages(TO_PAGES(sizeof(FexExtended) + 1)); - memcpy(DriverExtendedHeader, fexE, sizeof(FexExtended)); - - DriverFile DrvFile = { - .Enabled = true, - .BuiltIn = IsBuiltIn, - .DriverUID = this->DriverUIDs - 1, - .Address = (void *)fex, - .ExtendedHeaderAddress = (void *)DriverExtendedHeader, - .InterruptCallback = (void *)((uintptr_t)fex + (uintptr_t)fexE->Driver.InterruptCallback), - .MemTrk = mem, - }; - - if (fexE->Driver.InterruptCallback) - { - for (uint16_t i = 0; i < sizeof(fexE->Driver.Bind.Interrupt.Vector) / sizeof(fexE->Driver.Bind.Interrupt.Vector[0]); i++) - { - if (fexE->Driver.Bind.Interrupt.Vector[i] == 0) - break; - DrvFile.InterruptHook[i] = new DriverInterruptHook(fexE->Driver.Bind.Interrupt.Vector[i], DrvFile); - } - } - - KernelCallback KCallback{}; - KCallback.RawPtr = nullptr; - KCallback.Reason = CallbackReason::ConfigurationReason; - DriverCode CallbackRet = ((DriverCode(*)(KernelCallback *))((uintptr_t)fexE->Driver.Callback + (uintptr_t)fex))(&KCallback); - - if (CallbackRet != DriverCode::OK) - { - error("Driver %s returned error %d", fexE->Driver.Name, CallbackRet); - delete mem; - return CallbackRet; - } - - Drivers.push_back(DrvFile); - return DriverCode::OK; - } - default: - { - warn("Unknown driver type: %d", fexE->Driver.Type); - delete mem; - return DriverCode::UNKNOWN_DRIVER_TYPE; - } - } - } -} diff --git a/Core/Driver/DriverBinding/BindPCI.cpp b/Core/Driver/DriverBinding/BindPCI.cpp deleted file mode 100644 index 9311aabe..00000000 --- a/Core/Driver/DriverBinding/BindPCI.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../api.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include "../../../kernel.h" -#include "../../../DAPI.hpp" -#include "../../../Fex.hpp" - -namespace Driver -{ - DriverCode Driver::DriverLoadBindPCI(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn) - { - FexExtended *DrvExtHdr = (FexExtended *)(DriverAddress + EXTENDED_SECTION_ADDRESS); - if (IsBuiltIn) - DrvExtHdr = (FexExtended *)(((BuiltInDriverInfo *)DriverAddress)->ExtendedHeader); - - uint16_t SizeOfVendorID = sizeof(DrvExtHdr->Driver.Bind.PCI.VendorID) / - sizeof(DrvExtHdr->Driver.Bind.PCI.VendorID[0]); - uint16_t SizeOfDeviceID = sizeof(DrvExtHdr->Driver.Bind.PCI.DeviceID) / - sizeof(DrvExtHdr->Driver.Bind.PCI.DeviceID[0]); - - for (uint16_t vID = 0; vID < SizeOfVendorID; vID++) - { - for (uint16_t dID = 0; dID < SizeOfDeviceID; dID++) - { - if (DrvExtHdr->Driver.Bind.PCI.VendorID[vID] == 0 || - DrvExtHdr->Driver.Bind.PCI.DeviceID[dID] == 0) - continue; - - std::vector devices = - PCIManager->FindPCIDevice(DrvExtHdr->Driver.Bind.PCI.VendorID[vID], - DrvExtHdr->Driver.Bind.PCI.DeviceID[dID]); - if (devices.size() == 0) - continue; - - foreach (auto PCIDevice in devices) - { - debug("[%ld] VendorID: %#x; DeviceID: %#x", - devices.size(), PCIDevice->VendorID, PCIDevice->DeviceID); - - Memory::MemMgr *mem = new Memory::MemMgr(nullptr, thisProcess->memDirectory); - - BuiltInDriverInfo *bidi = (BuiltInDriverInfo *)DriverAddress; - Fex *fex = nullptr; - if (!IsBuiltIn) - { - fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1)); - memcpy(fex, (void *)DriverAddress, Size); - debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); - } - else - fex = (Fex *)bidi->EntryPoint; - DriverCode ret = CallDriverEntryPoint(fex, IsBuiltIn); - if (ret != DriverCode::OK) - { - delete mem; - return ret; - } - - if (IsBuiltIn) - fex = 0x0; /* Addresses are absolute if built-in. */ - - FexExtended *fexE = IsBuiltIn ? (FexExtended *)bidi->ExtendedHeader : (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); - debug("Starting driver %s", fexE->Driver.Name); - - PCIManager->MapPCIAddresses(PCIDevice); - - switch (fexE->Driver.Type) - { - case FexDriverType::FexDriverType_Generic: - case FexDriverType::FexDriverType_Display: - case FexDriverType::FexDriverType_Network: - case FexDriverType::FexDriverType_Storage: - case FexDriverType::FexDriverType_FileSystem: - case FexDriverType::FexDriverType_Input: - case FexDriverType::FexDriverType_Audio: - { - FexExtended *DriverExtendedHeader = (FexExtended *)mem->RequestPages(TO_PAGES(sizeof(FexExtended) + 1)); - memcpy(DriverExtendedHeader, fexE, sizeof(FexExtended)); - - DriverFile DrvFile = { - .Enabled = true, - .BuiltIn = IsBuiltIn, - .DriverUID = this->DriverUIDs - 1, - .Address = (void *)fex, - .ExtendedHeaderAddress = (void *)DriverExtendedHeader, - .InterruptCallback = (void *)((uintptr_t)fex + (uintptr_t)fexE->Driver.InterruptCallback), - .MemTrk = mem, - }; - - if (fexE->Driver.InterruptCallback) - DrvFile.InterruptHook[0] = new DriverInterruptHook(((int)((PCI::PCIHeader0 *)PCIDevice)->InterruptLine), DrvFile); - - KernelCallback KCallback{}; - KCallback.RawPtr = PCIDevice; - KCallback.Reason = CallbackReason::ConfigurationReason; - DriverCode CallbackRet = ((DriverCode(*)(KernelCallback *))((uintptr_t)fexE->Driver.Callback + (uintptr_t)fex))(&KCallback); - - if (CallbackRet != DriverCode::OK) - { - error("Driver %s returned error %d", fexE->Driver.Name, CallbackRet); - delete mem; - return CallbackRet; - } - - Drivers.push_back(DrvFile); - return DriverCode::OK; - } - default: - { - warn("Unknown driver type: %d", fexE->Driver.Type); - delete mem; - return DriverCode::UNKNOWN_DRIVER_TYPE; - } - } - } - } - } - return DriverCode::PCI_DEVICE_NOT_FOUND; - } -} diff --git a/Core/Driver/DriverBinding/BindProcess.cpp b/Core/Driver/DriverBinding/BindProcess.cpp deleted file mode 100644 index 188ef734..00000000 --- a/Core/Driver/DriverBinding/BindProcess.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../api.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include "../../../kernel.h" -#include "../../../DAPI.hpp" -#include "../../../Fex.hpp" - -namespace Driver -{ - DriverCode Driver::DriverLoadBindProcess(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn) - { - stub; - UNUSED(DriverAddress); - UNUSED(Size); - UNUSED(IsBuiltIn); - return DriverCode::NOT_IMPLEMENTED; - } -} diff --git a/Core/Driver/api.hpp b/Core/Driver/api.hpp deleted file mode 100644 index 46367260..00000000 --- a/Core/Driver/api.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_DRIVER_API_H__ -#define __FENNIX_KERNEL_DRIVER_API_H__ - -#include - -#include "../../DAPI.hpp" - -extern KernelAPI KernelAPITemplate; - -#endif // !__FENNIX_KERNEL_DRIVER_API_H__ diff --git a/Core/Memory/HeapAllocators/Xalloc/Wrapper.cpp b/Core/Memory/HeapAllocators/Xalloc/Wrapper.cpp deleted file mode 100644 index b80d0747..00000000 --- a/Core/Memory/HeapAllocators/Xalloc/Wrapper.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "Xalloc.hpp" - -#include - -extern "C" void *Xalloc_REQUEST_PAGES(Xsize_t Pages) -{ - return KernelAllocator.RequestPages(Pages); -} - -extern "C" void Xalloc_FREE_PAGES(void *Address, Xsize_t Pages) -{ - KernelAllocator.FreePages(Address, Pages); -} - -extern "C" void Xalloc_MAP_MEMORY(void *VirtualAddress, void *PhysicalAddress, Xsize_t Flags) -{ - Memory::Virtual(KernelPageTable).Map(VirtualAddress, PhysicalAddress, Flags); -} - -extern "C" void Xalloc_UNMAP_MEMORY(void *VirtualAddress) -{ - Memory::Virtual(KernelPageTable).Unmap(VirtualAddress); -} diff --git a/Core/Memory/MemoryManager.cpp b/Core/Memory/MemoryManager.cpp deleted file mode 100644 index f8b46ad3..00000000 --- a/Core/Memory/MemoryManager.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -#include "../../kernel.h" - -namespace Memory -{ - ReadFSFunction(MEM_Read) - { - if (Size <= 0) - Size = node->Length; - - if (RefOffset > node->Length) - return 0; - - if (RefOffset + (off_t)Size > node->Length) - Size = node->Length - RefOffset; - - memcpy(Buffer, (uint8_t *)(node->Address + RefOffset), Size); - return Size; - } - - WriteFSFunction(MEM_Write) - { - if (Size <= 0) - Size = node->Length; - - if (RefOffset > node->Length) - return 0; - - if (RefOffset + (off_t)Size > node->Length) - Size = node->Length - RefOffset; - - memcpy((uint8_t *)(node->Address + RefOffset), Buffer, Size); - return Size; - } - - VirtualFileSystem::FileSystemOperations mem_op = { - .Name = "mem", - .Read = MEM_Read, - .Write = MEM_Write, - }; - - uint64_t MemMgr::GetAllocatedMemorySize() - { - SmartLock(MgrLock); - uint64_t Size = 0; - foreach (auto ap in AllocatedPagesList) - Size += ap.PageCount; - return FROM_PAGES(Size); - } - - bool MemMgr::Add(void *Address, size_t Count) - { - SmartLock(MgrLock); - if (Address == nullptr) - { - error("Address is null!"); - return false; - } - - if (Count == 0) - { - error("Count is 0!"); - return false; - } - - for (size_t i = 0; i < AllocatedPagesList.size(); i++) - { - if (AllocatedPagesList[i].Address == Address) - { - error("Address already exists!"); - return false; - } - else if ((uintptr_t)Address < (uintptr_t)AllocatedPagesList[i].Address) - { - if ((uintptr_t)Address + (Count * PAGE_SIZE) > (uintptr_t)AllocatedPagesList[i].Address) - { - error("Address intersects with an allocated page!"); - return false; - } - } - else - { - if ((uintptr_t)AllocatedPagesList[i].Address + (AllocatedPagesList[i].PageCount * PAGE_SIZE) > (uintptr_t)Address) - { - error("Address intersects with an allocated page!"); - return false; - } - } - } - - if (this->Directory) - { - char FileName[64]; -#if defined(a64) || defined(aa64) - sprintf(FileName, "%lx-%ld", (uintptr_t)Address, Count); -#elif defined(a32) - sprintf(FileName, "%x-%ld", (uintptr_t)Address, Count); -#endif - VirtualFileSystem::Node *n = vfs->Create(FileName, VirtualFileSystem::NodeFlags::FILE, this->Directory); - if (n) - { - n->Address = (uintptr_t)Address; - n->Length = Count * PAGE_SIZE; - n->Operator = &mem_op; - } - } - - AllocatedPagesList.push_back({Address, Count}); - return true; - } - - void *MemMgr::RequestPages(size_t Count, bool User) - { - SmartLock(MgrLock); - void *Address = KernelAllocator.RequestPages(Count); - for (size_t i = 0; i < Count; i++) - { - int Flags = Memory::PTFlag::RW; - if (User) - Flags |= Memory::PTFlag::US; - - void *AddressToMap = (void *)((uintptr_t)Address + (i * PAGE_SIZE)); - - Memory::Virtual vmm = Memory::Virtual(this->Table); - vmm.Remap(AddressToMap, AddressToMap, Flags); - } - - if (this->Directory) - { - char FileName[64]; -#if defined(a64) || defined(aa64) - sprintf(FileName, "%lx-%ld", (uintptr_t)Address, Count); -#elif defined(a32) - sprintf(FileName, "%x-%ld", (uintptr_t)Address, Count); -#endif - VirtualFileSystem::Node *n = vfs->Create(FileName, VirtualFileSystem::NodeFlags::FILE, this->Directory); - if (n) // If null, error or file already exists - { - n->Address = (uintptr_t)Address; - n->Length = Count * PAGE_SIZE; - n->Operator = &mem_op; - } - } - - AllocatedPagesList.push_back({Address, Count}); - - /* For security reasons, we clear the allocated page - if it's a user page. */ - if (User) - memset(Address, 0, Count * PAGE_SIZE); - - return Address; - } - - void MemMgr::FreePages(void *Address, size_t Count) - { - SmartLock(MgrLock); - forItr(itr, AllocatedPagesList) - { - if (itr->Address == Address) - { - /** TODO: Advanced checks. Allow if the page count is less than the requested one. - * This will allow the user to free only a part of the allocated pages. - * - * But this will be in a separate function because we need to specify if we - * want to free from the start or from the end and return the new address. - */ - if (itr->PageCount != Count) - { - error("Page count mismatch! (Allocated: %lld, Requested: %lld)", itr->PageCount, Count); - return; - } - - KernelAllocator.FreePages(Address, Count); - - Memory::Virtual vmm = Memory::Virtual(this->Table); - for (size_t i = 0; i < Count; i++) - { - void *AddressToMap = (void *)((uintptr_t)Address + (i * PAGE_SIZE)); - vmm.Remap(AddressToMap, AddressToMap, Memory::PTFlag::RW); - // vmm.Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE))); - } - - if (this->Directory) - { - char FileName[64]; -#if defined(a64) || defined(aa64) - sprintf(FileName, "%lx-%ld", (uintptr_t)Address, Count); -#elif defined(a32) - sprintf(FileName, "%x-%ld", (uintptr_t)Address, Count); -#endif - if (!vfs->Delete(FileName, false, this->Directory)) - error("Failed to delete file %s", FileName); - } - - AllocatedPagesList.erase(itr); - return; - } - } - } - - void MemMgr::DetachAddress(void *Address) - { - SmartLock(MgrLock); - forItr(itr, AllocatedPagesList) - { - if (itr->Address == Address) - { - if (this->Directory) - { - char FileName[64]; -#if defined(a64) || defined(aa64) - sprintf(FileName, "%lx-%ld", (uintptr_t)Address, itr->PageCount); -#elif defined(a32) - sprintf(FileName, "%x-%ld", (uintptr_t)Address, itr->PageCount); -#endif - if (!vfs->Delete(FileName, false, this->Directory)) - error("Failed to delete file %s", FileName); - } - - AllocatedPagesList.erase(itr); - return; - } - } - } - - MemMgr::MemMgr(PageTable *Table, VirtualFileSystem::Node *Directory) - { - SmartLock(MgrLock); - if (Table) - this->Table = Table; - else - { -#if defined(a64) - this->Table = (PageTable *)CPU::x64::readcr3().raw; -#elif defined(a32) - this->Table = (PageTable *)CPU::x32::readcr3().raw; -#endif - } - - this->Directory = Directory; - debug("+ %#lx %s", this, - KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : ""); - } - - MemMgr::~MemMgr() - { - SmartLock(MgrLock); - foreach (auto ap in AllocatedPagesList) - { - KernelAllocator.FreePages(ap.Address, ap.PageCount); - Memory::Virtual vmm = Memory::Virtual(this->Table); - for (size_t i = 0; i < ap.PageCount; i++) - vmm.Remap((void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), - (void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), - Memory::PTFlag::RW); - } - - if (this->Directory) - { - foreach (auto Child in this->Directory->Children) - vfs->Delete(Child, true); - } - - debug("- %#lx %s", this, - KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : ""); - } -} diff --git a/Core/Memory/ProgramBreak.cpp b/Core/Memory/ProgramBreak.cpp deleted file mode 100644 index 9c2b5a46..00000000 --- a/Core/Memory/ProgramBreak.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -#include - -namespace Memory -{ - void *ProgramBreak::brk(void *Address) - { - if (HeapStart == 0x0 || Break == 0x0) - { - error("HeapStart or Break is 0x0"); - return (void *)-EAGAIN; - } - - /* Get the current program break. */ - if (Address == nullptr) - return (void *)Break; - - /* Check if the address is valid. */ - if (Address < (void *)HeapStart) - return (void *)-ENOMEM; - - Virtual vmm = Virtual(this->Table); - - if (Address > (void *)Break) - { - /* Allocate more memory. */ - size_t Pages = TO_PAGES(uintptr_t(Address) - Break); - void *Allocated = mm->RequestPages(Pages); - if (Allocated == nullptr) - return (void *)-ENOMEM; - - /* Map the allocated pages. */ - for (size_t i = 0; i < Pages; i++) - { - void *VirtAddr = (void *)(Break + (i * PAGE_SIZE)); - void *PhysAddr = (void *)(uintptr_t(Allocated) + (i * PAGE_SIZE)); - vmm.Map(VirtAddr, PhysAddr, RW | US); - } - - Break = (uint64_t)Address; - return (void *)Break; - } - else if (Address < (void *)Break) - { - /* Free memory. */ - size_t Pages = TO_PAGES(uintptr_t(Address) - Break); - mm->FreePages((void *)Break, Pages); - - /* Unmap the freed pages. */ - for (size_t i = 0; i < Pages; i++) - { - uint64_t Page = Break - (i * 0x1000); - vmm.Unmap((void *)Page); - } - - Break = (uint64_t)Address; - return (void *)Break; - } - - assert(false); - } - - ProgramBreak::ProgramBreak(PageTable *Table, MemMgr *mm) - { - assert(Table != nullptr); - assert(mm != nullptr); - - this->Table = Table; - this->mm = mm; - } - - ProgramBreak::~ProgramBreak() - { - /* Do nothing because MemMgr - will be destroyed later. */ - } -} diff --git a/Core/Memory/SmartHeap.cpp b/Core/Memory/SmartHeap.cpp deleted file mode 100644 index 48884ef6..00000000 --- a/Core/Memory/SmartHeap.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include - -namespace Memory -{ - SmartHeap::SmartHeap(size_t Size) - { - this->Object = kmalloc(Size); - this->ObjectSize = Size; - } - - SmartHeap::~SmartHeap() - { - kfree(this->Object); - } -} diff --git a/Core/Memory/StackGuard.cpp b/Core/Memory/StackGuard.cpp deleted file mode 100644 index a506f2cd..00000000 --- a/Core/Memory/StackGuard.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include - -namespace Memory -{ - bool StackGuard::Expand(uintptr_t FaultAddress) - { - if (this->UserMode) - { - if (FaultAddress < (uintptr_t)this->StackBottom - USER_STACK_SIZE || - FaultAddress > (uintptr_t)this->StackTop) - { - info("Fault address %#lx is not in range of stack %#lx - %#lx", FaultAddress, - (uintptr_t)this->StackBottom - USER_STACK_SIZE, (uintptr_t)this->StackTop); - return false; /* It's not about the stack. */ - } - else - { - void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); - debug("AllocatedStack: %#lx", AllocatedStack); - memset(AllocatedStack, 0, USER_STACK_SIZE); - - Virtual va = Virtual(this->Table); - for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) - { - void *VirtualPage = (void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)); - void *PhysicalPage = (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)); - - va.Map(VirtualPage, PhysicalPage, PTFlag::RW | PTFlag::US); - AllocatedPages pa = { - .PhysicalAddress = PhysicalPage, - .VirtualAddress = VirtualPage, - }; - AllocatedPagesList.push_back(pa); - debug("Mapped %#lx to %#lx", PhysicalPage, VirtualPage); - } - - this->StackBottom = (void *)((uintptr_t)this->StackBottom - USER_STACK_SIZE); - this->Size += USER_STACK_SIZE; - info("Stack expanded to %#lx", this->StackBottom); - this->Expanded = true; - return true; - } - } - else - { - fixme("Not implemented and probably not needed"); - return false; - } - } - - void StackGuard::Fork(StackGuard *Parent) - { - this->UserMode = Parent->GetUserMode(); - this->StackBottom = Parent->GetStackBottom(); - this->StackTop = Parent->GetStackTop(); - this->StackPhysicalBottom = Parent->GetStackPhysicalBottom(); - this->StackPhysicalTop = Parent->GetStackPhysicalTop(); - this->Size = Parent->GetSize(); - this->Expanded = Parent->IsExpanded(); - - if (this->UserMode) - { - std::vector ParentAllocatedPages = Parent->GetAllocatedPages(); - - Virtual va = Virtual(Table); - - foreach (auto Page in AllocatedPagesList) - { - va.Unmap(Page.VirtualAddress); - KernelAllocator.FreePage(Page.PhysicalAddress); - debug("Freed %#lx and unmapped %#lx", Page.PhysicalAddress, Page.VirtualAddress); - } - - foreach (auto Page in ParentAllocatedPages) - { - void *NewPhysical = KernelAllocator.RequestPage(); - memcpy(NewPhysical, Page.PhysicalAddress, PAGE_SIZE); - va.Map(Page.VirtualAddress, NewPhysical, PTFlag::RW | PTFlag::US); - - AllocatedPages pa = { - .PhysicalAddress = NewPhysical, - .VirtualAddress = Page.VirtualAddress, - }; - AllocatedPagesList.push_back(pa); - debug("Mapped %#lx to %#lx", NewPhysical, Page.VirtualAddress); - } - } - else - { - fixme("Kernel mode stack fork not implemented"); - } - } - - StackGuard::StackGuard(bool User, PageTable *Table) - { - this->UserMode = User; - this->Table = Table; - - if (this->UserMode) - { - void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); - memset(AllocatedStack, 0, USER_STACK_SIZE); - debug("AllocatedStack: %#lx", AllocatedStack); - - Virtual va = Virtual(Table); - for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) - { - void *VirtualPage = (void *)(USER_STACK_BASE + (i * PAGE_SIZE)); - void *PhysicalPage = (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)); - va.Map(VirtualPage, PhysicalPage, PTFlag::RW | PTFlag::US); - - AllocatedPages pa = { - .PhysicalAddress = PhysicalPage, - .VirtualAddress = VirtualPage, - }; - AllocatedPagesList.push_back(pa); - debug("Mapped %#lx to %#lx", PhysicalPage, VirtualPage); - } - - this->StackBottom = (void *)USER_STACK_BASE; - this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE); - - this->StackPhysicalBottom = AllocatedStack; - this->StackPhysicalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE); - - this->Size = USER_STACK_SIZE; - } - else - { - this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); - memset(this->StackBottom, 0, STACK_SIZE); - debug("StackBottom: %#lx", this->StackBottom); - - this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE); - - this->StackPhysicalBottom = this->StackBottom; - this->StackPhysicalTop = this->StackTop; - - this->Size = STACK_SIZE; - - for (size_t i = 0; i < TO_PAGES(STACK_SIZE); i++) - { - AllocatedPages pa = { - .PhysicalAddress = (void *)((uintptr_t)this->StackBottom + (i * PAGE_SIZE)), - .VirtualAddress = (void *)((uintptr_t)this->StackBottom + (i * PAGE_SIZE)), - }; - AllocatedPagesList.push_back(pa); - } - } - - debug("Allocated stack at %#lx", this->StackBottom); - } - - StackGuard::~StackGuard() - { - foreach (auto Page in AllocatedPagesList) - { - KernelAllocator.FreePage(Page.PhysicalAddress); - debug("Freed page at %#lx", Page.PhysicalAddress); - } - } -} diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp deleted file mode 100644 index 61b5e111..00000000 --- a/Core/Memory/VirtualMemoryManager.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -namespace Memory -{ - Virtual::Virtual(PageTable *Table) - { - if (Table) - this->Table = Table; - else - this->Table = (PageTable *)CPU::PageTable(); - } - - Virtual::~Virtual() {} -} diff --git a/Core/README.md b/Core/README.md deleted file mode 100644 index a2ef85f5..00000000 --- a/Core/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Core components - -This directory contains the core components of the project. These components are used by the kernel to provide the basic functionality of the operating system. - ---- - -## 💾 Memory - -Contains the memory management code. -It is responsible for allocating and freeing memory. -It also provides the `kmalloc`, `kcalloc`, `krealloc` and `kfree` functions that are used by the rest of the kernel. - -## 📺 Video - -Contains the video management code. -It is responsible for printing text to the screen. - -## 🖥 CPU - -Contains the CPU management code. -It is responsible for initializing the GDT and IDT. -More code related is in the `Architecture` directory. diff --git a/Core/crashhandler.hpp b/Core/crashhandler.hpp deleted file mode 100644 index 0a9fc11b..00000000 --- a/Core/crashhandler.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_CRASH_HANDLER_H__ -#define __FENNIX_KERNEL_CRASH_HANDLER_H__ - -#include - -#include -#include - -namespace CrashHandler -{ - extern uintptr_t PageFaultAddress; - extern void *EHIntFrames[INT_FRAMES_MAX]; - - void EHPrint(const char *Format, ...); - void Handle(void *Data); -} - -#endif // !__FENNIX_KERNEL_CRASH_HANDLER_H__ diff --git a/Fex.hpp b/Fex.hpp index b1d7e76d..86c9fc66 100644 --- a/Fex.hpp +++ b/Fex.hpp @@ -1,33 +1,33 @@ /* - BSD 3-Clause License + BSD 3-Clause License - Copyright (c) 2023, EnderIce2 - All rights reserved. + Copyright (c) 2023, EnderIce2 + All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FENNIX_FILE_FEX_H__ @@ -50,7 +50,7 @@ enum FexFormatType { FexFormatType_Unknown, FexFormatType_Executable, - FexFormatType_Driver + FexFormatType_Module /* ... */ }; @@ -62,17 +62,17 @@ enum FexOSType /* ... */ }; -enum FexDriverType +enum FexModuleType { - FexDriverType_Unknown, - FexDriverType_Generic, - FexDriverType_Display, - FexDriverType_Network, - FexDriverType_Storage, - FexDriverType_FileSystem, - FexDriverType_Input, - FexDriverType_Audio, - FexDriverType_ACPI, + FexModuleType_Unknown, + FexModuleType_Generic, + FexModuleType_Display, + FexModuleType_Network, + FexModuleType_Storage, + FexModuleType_FileSystem, + FexModuleType_Input, + FexModuleType_Audio, + FexModuleType_ACPI, /* ... */ }; @@ -105,13 +105,13 @@ struct FexExtended struct { char Name[64]; - enum FexDriverType Type : 4; + enum FexModuleType Type : 4; enum FexDriverInputTypes TypeFlags : 4; char OverrideOnConflict; int (*Callback)(union KernelCallback *); int (*InterruptCallback)(union CPURegisters *); - struct DriverBind + struct ModuleBind { int Type; struct @@ -139,7 +139,7 @@ struct FexExtended char AttachToKeyboard; } Input; } Bind; - } Driver; + } Module; } __attribute__((packed)); /** diff --git a/FileSystem/FS/ustar.cpp b/FileSystem/FS/ustar.cpp deleted file mode 100644 index 56a84fb9..00000000 --- a/FileSystem/FS/ustar.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include - -#include "../../kernel.h" - -namespace VirtualFileSystem -{ - ReadFSFunction(USTAR_Read) - { - if (Size <= 0) - Size = node->Length; - - if (RefOffset > node->Length) - return 0; - - if (RefOffset + (off_t)Size > node->Length) - Size = node->Length - RefOffset; - - memcpy(Buffer, (uint8_t *)(node->Address + RefOffset), Size); - return Size; - } - - FileSystemOperations ustar_op = { - .Name = "ustar", - .Read = USTAR_Read, - }; - - bool USTAR::TestArchive(uintptr_t Address) - { - if (!Memory::Virtual().Check((void *)Address)) - { - error("Address %#lx is not mapped!", Address); - return false; - } - - if (memcmp(((FileHeader *)(uintptr_t)Address)->signature, "ustar", 5) != 0) - { - error("ustar signature invalid!"); - return false; - } - return true; - } - - void USTAR::ReadArchive(uintptr_t Address, Virtual *vfs_ctx) - { - trace("Initializing USTAR with address %#llx", Address); - - if (!this->TestArchive(Address)) - return; /* Check whether the archive is deflated */ - - debug("USTAR signature valid! Name:%s Signature:%s Mode:%c Size:%lu", - ((FileHeader *)Address)->name, - ((FileHeader *)Address)->signature, - string2int(((FileHeader *)Address)->mode), - ((FileHeader *)Address)->size); - - vfs_ctx->CreateRoot("/", &ustar_op); - - for (size_t i = 0;; i++) - { - FileHeader *header = (FileHeader *)Address; - if (memcmp(((FileHeader *)Address)->signature, "ustar", 5) != 0) - break; - memmove(header->name, header->name + 1, strlen(header->name)); - if (header->name[strlen(header->name) - 1] == '/') - header->name[strlen(header->name) - 1] = 0; - size_t size = getsize(header->size); - Node *node = nullptr; - - // if (!isempty((char *)header->name)) - // KPrint("Adding file \e88AACC%s\eCCCCCC (\e88AACC%lu \eCCCCCCbytes)", header->name, size); - // else - // goto NextFileAddress; - - if (isempty((char *)header->name)) - goto NextFileAddress; - - node = vfs_ctx->Create(header->name, NodeFlags::NODE_FLAG_ERROR); - debug("Added node: %s", node->Name); - if (node == nullptr) - { - static int ErrorsAllowed = 20; - - if (ErrorsAllowed > 0) - { - ErrorsAllowed--; - goto NextFileAddress; - } - else - { - error("Adding USTAR files failed because too many files were corrupted or invalid."); - break; - } - } - else - { - debug("%s %d KiB, Type:%c", header->name, TO_KiB(size), header->typeflag[0]); - node->Mode = string2int(header->mode); - node->Address = (Address + 512); - node->Length = size; - node->GroupIdentifier = getsize(header->gid); - node->UserIdentifier = getsize(header->uid); - node->IndexNode = i; - - switch (header->typeflag[0]) - { - case REGULAR_FILE: - node->Flags = NodeFlags::FILE; - break; - case SYMLINK: - node->Flags = NodeFlags::SYMLINK; - node->Symlink = new char[strlen(header->link) + 1]; - strncpy((char *)node->Symlink, header->link, strlen(header->link)); - break; - case DIRECTORY: - node->Flags = NodeFlags::DIRECTORY; - break; - case CHARDEV: - node->Flags = NodeFlags::CHARDEVICE; - break; - case BLOCKDEV: - node->Flags = NodeFlags::BLOCKDEVICE; - break; - default: - warn("Unknown type: %d", header->typeflag[0]); - break; - } - NextFileAddress: - Address += ((size / 512) + 1) * 512; - if (size % 512) - Address += 512; - } - } - } - - USTAR::USTAR() {} - - USTAR::~USTAR() {} -} diff --git a/FileSystem/FileNode.cpp b/FileSystem/FileNode.cpp deleted file mode 100644 index e08ea66b..00000000 --- a/FileSystem/FileNode.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#ifdef DEBUG -const char *SeekStrings[] = - {"SEEK_SET", - "SEEK_CUR", - "SEEK_END"}; -#endif - -namespace VirtualFileSystem -{ - ReferenceNode *Node::CreateReference() - { - SmartLock(NodeLock); - ReferenceNode *rn = new ReferenceNode(this); - References.push_back(rn); - debug("Created reference %p for node %p", rn, this); - return rn; - } - - void Node::RemoveReference(ReferenceNode *Reference) - { - SmartLock(NodeLock); - debug("Removing reference %p for node %p", Reference, this); - References.erase(std::find(References.begin(), References.end(), Reference)); - } - - /**************************************************************/ - - size_t ReferenceNode::Read(uint8_t *Buffer, size_t Size) - { - if (this->SymlinkTo) - return this->SymlinkTo->Read(Buffer, Size); - - if (!this->node->Operator) - { - errno = EFAULT; - return -1; - } - - SmartLock(RefNodeLock); - - if (this->node->Operator->Read) - { - off_t RefOffset = off_t(this->Offset.load()); - return this->node->Operator->Read(this->node, Size, Buffer, RefOffset); - } - - errno = ENOSYS; - return -1; - } - - size_t ReferenceNode::Write(uint8_t *Buffer, size_t Size) - { - if (this->SymlinkTo) - return this->SymlinkTo->Write(Buffer, Size); - - if (!this->node->Operator) - { - errno = EFAULT; - return -1; - } - - SmartLock(RefNodeLock); - - if (this->node->Operator->Write) - { - off_t RefOffset = off_t(this->Offset.load()); - return this->node->Operator->Write(this->node, Size, Buffer, RefOffset); - } - - errno = ENOSYS; - return -1; - } - - off_t ReferenceNode::Seek(off_t _Offset, int Whence) - { - if (this->SymlinkTo) - return this->SymlinkTo->Seek(_Offset, Whence); - - if (!this->node->Operator) - { - errno = EFAULT; - return -1; - } - - SmartLock(RefNodeLock); - - if (this->node->Operator->Seek) - { - off_t RefOffset = off_t(this->Offset.load()); - debug("The node has a seek function"); - return this->node->Operator->Seek(this->node, _Offset, Whence, RefOffset); - } - - // debug("Current offset is %d", this->Offset.load()); - switch (Whence) - { - case SEEK_SET: - { - if (_Offset > this->node->Length) - { - errno = EINVAL; - return -1; - } - - if (_Offset < 0) - { - fixme("Negative offset %d is not implemented", _Offset); - _Offset = 0; - } - - if (_Offset > this->node->Length) - { - fixme("Offset %d is bigger than file size %d", - _Offset, this->node->Length); - _Offset = this->node->Length; - } - - this->Offset.store(_Offset); - break; - } - case SEEK_CUR: - { - off_t NewOffset = off_t(this->Offset.load()) + _Offset; - if (NewOffset > this->node->Length || - NewOffset < 0) - { - errno = EINVAL; - return -1; - } - - this->Offset.store(NewOffset); - break; - } - case SEEK_END: - { - off_t NewOffset = this->node->Length + _Offset; - if (NewOffset > this->node->Length || - NewOffset < 0) - { - errno = EINVAL; - return -1; - } - - this->Offset.store(NewOffset); - break; - } - default: - { - error("Invalid whence!"); - errno = EINVAL; - return -1; - } - } - - off_t RetOffset = off_t(this->Offset.load()); - // debug("( %d %ld %s[%d] ) -> %d", - // _Offset, this->Offset.load(), - // SeekStrings[Whence], Whence, - // RetOffset); - return RetOffset; - } - - ReferenceNode::ReferenceNode(Node *node) - { - SmartLock(RefNodeLock); - this->node = node; - this->FileSize = node->Length; - this->AbsolutePath += node->FileSystem->GetPathFromNode(node); - if (this->node->Flags == SYMLINK) - { - if (!this->node->SymlinkTarget) - { - this->node->SymlinkTarget = - node->FileSystem->GetNodeFromPath(this->node->Symlink); - - /* not standard but useful in kernel-space */ - this->node->Length = this->node->SymlinkTarget->Length; - } - - if (!this->node->SymlinkTarget) - { - error("Symlink target %s not found!", - this->node->Symlink); - errno = ENOENT; - return; - } - - this->SymlinkTo = this->node->SymlinkTarget->CreateReference(); - } - - debug("Created reference node for %s [%#lx]", - this->AbsolutePath.c_str(), (uintptr_t)this); - } - - ReferenceNode::~ReferenceNode() - { - SmartLock(RefNodeLock); - if (this->SymlinkTo) - this->node->SymlinkTarget->RemoveReference(this); - this->node->RemoveReference(this); - - debug("Destroyed reference node for %s [%#lx]", - this->AbsolutePath.c_str(), (uintptr_t)this); - } -} diff --git a/FileSystem/Filesystem.cpp b/FileSystem/Filesystem.cpp deleted file mode 100644 index 086a67d7..00000000 --- a/FileSystem/Filesystem.cpp +++ /dev/null @@ -1,634 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include -#include -#include - -#include "../kernel.h" - -// show debug messages -// #define DEBUG_FILESYSTEM 1 - -#ifdef DEBUG_FILESYSTEM -#define vfsdbg(m, ...) debug(m, ##__VA_ARGS__) -#else -#define vfsdbg(m, ...) -#endif - -namespace VirtualFileSystem -{ - std::string Virtual::GetPathFromNode(Node *File) - { - vfsdbg("GetPathFromNode( Node: \"%s\" )", File->Name); - SmartLock(VirtualLock); - - Node *Parent = File; - char **Path = nullptr; - size_t PathSize = 0; - std::string FinalPath; - - while (Parent != FileSystemRoot && Parent != nullptr) - { - if (File == FileSystemRoot->Children[0]) - { - FinalPath = "/"; - break; - } - - bool Found = false; - foreach (const auto &Children in FileSystemRoot->Children) - if (Children == Parent) - { - Found = true; - break; - } - - if (Found) - break; - - if (strlen(Parent->Name) == 0) - break; - - char **new_path = new char *[PathSize + 1]; - if (Path != nullptr) - { - memcpy(new_path, Path, sizeof(char *) * PathSize); - delete[] Path; - } - - Path = new_path; - Path[PathSize] = (char *)Parent->Name; - PathSize++; - new_path = new char *[PathSize + 1]; - memcpy(new_path, Path, sizeof(char *) * PathSize); - delete[] Path; - Path = new_path; - Path[PathSize] = (char *)"/"; - PathSize++; - Parent = Parent->Parent; - } - - for (size_t i = PathSize - 1; i < PathSize; i--) - { - if (Path[i] == nullptr) - continue; - FinalPath += Path[i]; - } - - FinalPath += "\0"; - delete[] Path, Path = nullptr; - vfsdbg("GetPathFromNode()->\"%s\"", FinalPath.c_str()); - return FinalPath; - } - - Node *Virtual::GetNodeFromPath_Unsafe(const char *Path, Node *Parent) - { - vfsdbg("GetNodeFromPath( Path: \"%s\" Parent: \"%s\" )", - Path, Parent ? Parent->Name : "(null)"); - - if (strcmp(Path, "/") == 0) - return FileSystemRoot->Children[0]; // 0 - filesystem root - - if (strcmp(Path, ".") == 0) - return Parent; - - if (strcmp(Path, "..") == 0) - { - if (Parent) - { - if (Parent->Parent) - return Parent->Parent; - else - return Parent; - } - else - return nullptr; - } - - Node *ReturnNode = Parent; - bool IsAbsolutePath = cwk_path_is_absolute(Path); - - if (!ReturnNode) - ReturnNode = FileSystemRoot->Children[0]; // 0 - filesystem root - - if (IsAbsolutePath) - ReturnNode = FileSystemRoot->Children[0]; // 0 - filesystem root - - cwk_segment segment; - if (unlikely(!cwk_path_get_first_segment(Path, &segment))) - { - error("Path doesn't have any segments."); - errno = ENOENT; - return nullptr; - } - - do - { - char *SegmentName = new char[segment.end - segment.begin + 1]; - memcpy(SegmentName, segment.begin, segment.end - segment.begin); - vfsdbg("GetNodeFromPath()->SegmentName: \"%s\"", SegmentName); - GetNodeFromPathNextParent: - foreach (auto Child in ReturnNode->Children) - { - vfsdbg("comparing \"%s\" with \"%s\"", - Child->Name, SegmentName); - if (strcmp(Child->Name, SegmentName) == 0) - { - ReturnNode = Child; - goto GetNodeFromPathNextParent; - } - } - delete[] SegmentName; - } while (cwk_path_get_next_segment(&segment)); - - const char *basename; - cwk_path_get_basename(Path, &basename, nullptr); - vfsdbg("BaseName: \"%s\" NodeName: \"%s\"", - basename, ReturnNode->Name); - - if (strcmp(basename, ReturnNode->Name) == 0) - { - vfsdbg("GetNodeFromPath()->\"%s\"", ReturnNode->Name); - return ReturnNode; - } - - vfsdbg("GetNodeFromPath()->\"(null)\""); - errno = ENOENT; - return nullptr; - } - - Node *Virtual::GetNodeFromPath(const char *Path, Node *Parent) - { - SmartLock(VirtualLock); - return GetNodeFromPath_Unsafe(Path, Parent); - } - - bool Virtual::PathIsRelative(const char *Path) - { - vfsdbg("PathIsRelative( Path: \"%s\" )", Path); - bool IsRelative = cwk_path_is_relative(Path); - vfsdbg("PathIsRelative()->%s", IsRelative ? "true" : "false"); - return IsRelative; - } - - Node *Virtual::GetParent(const char *Path, Node *Parent) - { - vfsdbg("GetParent( Path: \"%s\" Parent: \"%s\" )", - Path, Parent->Name); - - if (Parent) - { - vfsdbg("GetParent()->\"%s\"", Parent->Name); - return Parent; - } - - Node *ParentNode = nullptr; - if (FileSystemRoot->Children.size() >= 1) - { - assert(FileSystemRoot->Children[0] != nullptr); - ParentNode = FileSystemRoot->Children[0]; // 0 - filesystem root - } - else - { - // TODO: Check if here is a bug or something... - const char *PathCopy; - PathCopy = (char *)Path; - size_t length; - cwk_path_get_root(PathCopy, &length); // not working? - if (length > 0) - { - foreach (auto Child in FileSystemRoot->Children) - { - if (strcmp(Child->Name, PathCopy) == 0) - { - ParentNode = Child; - break; - } - } - } - } - vfsdbg("GetParent()->\"%s\"", ParentNode->Name); - return ParentNode; - } - - Node *Virtual::AddNewChild(const char *Name, Node *Parent) - { - if (!Parent) - { - error("Parent is null!"); - return nullptr; - } - vfsdbg("AddNewChild( Name: \"%s\" Parent: \"%s\" )", - Name, Parent->Name); - - Node *newNode = new Node; - newNode->Parent = Parent; - newNode->Name = new char[strlen(Name) + 1]; - strncpy((char *)newNode->Name, Name, strlen(Name)); - - newNode->Operator = Parent->Operator; - newNode->FileSystem = this; - Parent->Children.push_back(newNode); - - vfsdbg("AddNewChild()->\"%s\"", newNode->Name); - return newNode; - } - - Node *Virtual::GetChild(const char *Name, Node *Parent) - { - vfsdbg("GetChild( Name: \"%s\" Parent: \"%s\" )", - Name, Parent->Name); - - if (!Parent) - { - vfsdbg("GetChild()->nullptr"); - return nullptr; - } - - foreach (auto Child in Parent->Children) - if (strcmp(Child->Name, Name) == 0) - { - vfsdbg("GetChild()->\"%s\"", Child->Name); - return Child; - } - vfsdbg("GetChild()->nullptr (not found)"); - return nullptr; - } - - int Virtual::RemoveChild(const char *Name, Node *Parent) - { - vfsdbg("RemoveChild( Name: \"%s\" Parent: \"%s\" )", - Name, Parent->Name); - - forItr(itr, Parent->Children) - { - if (strcmp((*itr)->Name, Name) == 0) - { - delete *itr, *itr = nullptr; - Parent->Children.erase(itr); - vfsdbg("RemoveChild()->OK"); - return 0; - } - } - - - vfsdbg("RemoveChild()->NotFound"); - return -1; - } - - std::string Virtual::NormalizePath(const char *Path, Node *Parent) - { - vfsdbg("NormalizePath( Path: \"%s\" Parent: \"%s\" )", - Path, Parent->Name); - - char *NormalizedPath = new char[strlen((char *)Path) + 1]; - std::string RelativePath; - - cwk_path_normalize(Path, NormalizedPath, strlen((char *)Path) + 1); - - if (cwk_path_is_relative(NormalizedPath)) - { - std::string ParentPath = GetPathFromNode(Parent); - size_t PathSize = cwk_path_join(ParentPath.c_str(), - NormalizedPath, - nullptr, 0); - - RelativePath.resize(PathSize + 1); - - cwk_path_join(ParentPath.c_str(), NormalizedPath, - (char *)RelativePath.c_str(), - PathSize + 1); - } - else - { - RelativePath = NormalizedPath; - } - delete[] NormalizedPath; - vfsdbg("NormalizePath()->\"%s\"", RelativePath.get()); - return RelativePath; - } - - bool Virtual::PathExists(const char *Path, Node *Parent) - { - if (isempty((char *)Path)) - { - vfsdbg("PathExists()->PathIsEmpty"); - return false; - } - - if (Parent == nullptr) - Parent = FileSystemRoot; - - vfsdbg("PathExists( Path: \"%s\" Parent: \"%s\" )", - Path, Parent->Name); - - if (GetNodeFromPath(NormalizePath(Path, Parent).c_str(), Parent)) - { - vfsdbg("PathExists()->OK"); - return true; - } - - vfsdbg("PathExists()->NotFound"); - return false; - } - - Node *Virtual::CreateRoot(const char *RootName, - FileSystemOperations *Operator) - { - if (Operator == nullptr) - return nullptr; - - debug("Creating root %s", RootName); - - SmartLock(VirtualLock); - Node *newNode = new Node; - newNode->Name = RootName; - newNode->Flags = NodeFlags::DIRECTORY; - newNode->Operator = Operator; - newNode->FileSystem = this; - FileSystemRoot->Children.push_back(newNode); - return newNode; - } - - /* TODO: Further testing needed */ - Node *Virtual::Create(const char *Path, NodeFlags Flag, Node *Parent) - { - if (isempty((char *)Path)) - return nullptr; - - SmartLock(VirtualLock); - Node *RootNode = FileSystemRoot->Children[0]; - Node *CurrentParent = this->GetParent(Path, Parent); - vfsdbg("Virtual::Create( Path: \"%s\" Parent: \"%s\" )", - Path, Parent ? Parent->Name : CurrentParent->Name); - - VirtualLock.Unlock(); - std::string CleanPath = this->NormalizePath(Path, CurrentParent); - VirtualLock.Lock(__FUNCTION__); - vfsdbg("CleanPath: \"%s\"", CleanPath.get()); - - VirtualLock.Unlock(); - if (PathExists(CleanPath.c_str(), CurrentParent)) - { - error("Path %s already exists.", CleanPath.c_str()); - goto CreatePathError; - } - VirtualLock.Lock(__FUNCTION__); - - cwk_segment segment; - if (!cwk_path_get_first_segment(CleanPath.c_str(), &segment)) - { - error("Path doesn't have any segments."); - goto CreatePathError; - } - - do - { - char *SegmentName = new char[segment.end - segment.begin + 1]; - memcpy(SegmentName, segment.begin, segment.end - segment.begin); - vfsdbg("SegmentName: \"%s\"", SegmentName); - - if (Parent) - { - if (GetChild(SegmentName, RootNode) != nullptr) - { - RootNode = GetChild(SegmentName, RootNode); - delete[] SegmentName; - continue; - } - } - - if (GetChild(SegmentName, CurrentParent) == nullptr) - { - CurrentParent = AddNewChild(SegmentName, CurrentParent); - CurrentParent->Flags = Flag; - } - else - { - CurrentParent = GetChild(SegmentName, CurrentParent); - } - - delete[] SegmentName; - } while (cwk_path_get_next_segment(&segment)); - - vfsdbg("Virtual::Create()->\"%s\"", CurrentParent->Name); -#ifdef DEBUG - VirtualLock.Unlock(); - debug("Path created: \"%s\"", - GetPathFromNode(CurrentParent).c_str()); - VirtualLock.Lock(__FUNCTION__); -#endif - return CurrentParent; - - CreatePathError: - vfsdbg("Virtual::Create()->nullptr"); - return nullptr; - } - - int Virtual::Delete(const char *Path, bool Recursive, Node *Parent) - { - vfsdbg("Virtual::Delete( Path: \"%s\" Parent: \"%s\" )", - Path, Parent ? Parent->Name : "(null)"); - - if (isempty((char *)Path)) - { - errno = EINVAL; - return -1; - } - - if (Parent == nullptr) - Parent = FileSystemRoot; - - std::string CleanPath = this->NormalizePath(Path, Parent); - vfsdbg("CleanPath: \"%s\"", CleanPath.c_str()); - - if (!PathExists(CleanPath.c_str(), Parent)) - { - vfsdbg("Path %s doesn't exist.", CleanPath.c_str()); - errno = ENOENT; - return -1; - } - - Node *NodeToDelete = GetNodeFromPath(CleanPath.c_str(), Parent); - - if (NodeToDelete->Flags == NodeFlags::DIRECTORY) - { - SmartLock(VirtualLock); - if (Recursive) - { - foreach (auto Child in NodeToDelete->Children) - { - VirtualLock.Unlock(); - int Status = Delete(GetPathFromNode(Child).c_str(), true); - VirtualLock.Lock(__FUNCTION__); - if (Status != 0) - { - error("Failed to delete child %s with status %d. (%s)", - Child->Name, Status, Path); - errno = EIO; - return -1; - } - } - } - else if (NodeToDelete->Children.size() > 0) - { - error("Directory %s is not empty.", CleanPath.c_str()); - errno = ENOTEMPTY; - return -1; - } - } - - SmartLock(VirtualLock); - Node *ParentNode = GetParent(CleanPath.c_str(), Parent); - if (RemoveChild(NodeToDelete->Name, ParentNode) != 0) - { - error("Failed to remove child %s from parent %s. (%s)", NodeToDelete->Name, ParentNode->Name, Path); - errno = EIO; - return -1; - } - - debug("Deleted %s", CleanPath.c_str()); - vfsdbg("Virtual::Delete()->OK"); - return 0; - } - - int Virtual::Delete(Node *Path, bool Recursive, Node *Parent) - { - std::string PathString = GetPathFromNode(Path); - return Delete(PathString.c_str(), Recursive, Parent); - } - - /* TODO: REWORK */ - Node *Virtual::Mount(const char *Path, FileSystemOperations *Operator) - { - if (unlikely(!Operator)) - { - errno = EFAULT; - return nullptr; - } - - if (unlikely(isempty((char *)Path))) - { - errno = EINVAL; - return nullptr; - } - - vfsdbg("Mounting %s", Path); - const char *PathCopy; - cwk_path_get_basename(Path, &PathCopy, 0); - Node *MountPoint = Create(Path, NodeFlags::MOUNTPOINT); - MountPoint->Operator = Operator; - return MountPoint; - } - - int Virtual::Unmount(Node *File) - { - if (unlikely(!File)) - { - errno = EINVAL; - return -1; - } - - if (unlikely(File->Flags != NodeFlags::MOUNTPOINT)) - { - errno = ENOTDIR; - return -1; - } - - fixme("Unmounting %s", - File->Name); - errno = ENOSYS; - return -1; - } - - RefNode *Virtual::Open(const char *Path, Node *Parent) - { - vfsdbg("Opening %s with parent %s", Path, Parent ? Parent->Name : "(null)"); - - if (strcmp(Path, "/") == 0) - return FileSystemRoot->CreateReference(); - - if (!Parent) - Parent = FileSystemRoot->Children[0]; - - if (strcmp(Path, ".") == 0) - return Parent->CreateReference(); - - if (strcmp(Path, "..") == 0) - { - if (Parent->Parent) - return Parent->Parent->CreateReference(); - else - return Parent->CreateReference(); - } - - Node *CurrentParent = this->GetParent(Path, Parent); - std::string CleanPath = NormalizePath(Path, CurrentParent); - - /* TODO: Check for other errors */ - if (!PathExists(CleanPath.c_str(), CurrentParent)) - { - { - SmartLock(VirtualLock); - foreach (auto Child in FileSystemRoot->Children) - { - if (strcmp(Child->Name, CleanPath.c_str()) != 0) - continue; - - return Child->CreateReference(); - } - } - - Node *node = GetNodeFromPath(CleanPath.c_str(), FileSystemRoot->Children[0]); - if (node) - return node->CreateReference(); - } - else - { - Node *node = GetNodeFromPath(CleanPath.c_str(), CurrentParent); - if (node) - return node->CreateReference(); - } - - errno = ENOENT; - return nullptr; - } - - Virtual::Virtual() - { - SmartLock(VirtualLock); - trace("Initializing virtual file system..."); - FileSystemRoot = new Node; - FileSystemRoot->Flags = NodeFlags::MOUNTPOINT; - FileSystemRoot->Operator = nullptr; - FileSystemRoot->Parent = nullptr; - FileSystemRoot->Name = "root"; - FileSystemRoot->FileSystem = this; - cwk_path_set_style(CWK_STYLE_UNIX); - } - - Virtual::~Virtual() - { - SmartLock(VirtualLock); - stub; - /* TODO: sync, cache */ - } -} diff --git a/FileSystem/Mounts/Null.cpp b/FileSystem/Mounts/Null.cpp deleted file mode 100644 index 1630149d..00000000 --- a/FileSystem/Mounts/Null.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -ReadFSFunction(Null_Read) -{ - if (Size <= 0) - return 0; - - memset(Buffer, 0, Size); - return Size; -} - -ReadFSFunction(Null_Write) -{ - return Size; -} - -FileSystemOperations null_op = { - .Name = "Null", - .Read = Null_Read, - .Write = Null_Write, -}; - -void Init_Null(Virtual *vfs_ctx) -{ - Node *n = vfs_ctx->Create("null", CHARDEVICE, DevFS); - n->Operator = &null_op; -} diff --git a/FileSystem/Mounts/Random.cpp b/FileSystem/Mounts/Random.cpp deleted file mode 100644 index 69081898..00000000 --- a/FileSystem/Mounts/Random.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -ReadFSFunction(Random_Read) -{ - if (Size <= 0) - return 0; - - uint64_t *buf = (uint64_t *)Buffer; - for (size_t i = 0; i < Size / sizeof(uint64_t); i++) - buf[i] = Random::rand64(); - return Size; -} - -ReadFSFunction(Random_Write) -{ - return Size; -} - -FileSystemOperations random_op = { - .Name = "Random", - .Read = Random_Read, - .Write = Random_Write, -}; - -void Init_Random(Virtual *vfs_ctx) -{ - Node *n = vfs_ctx->Create("random", CHARDEVICE, DevFS); - n->Operator = &random_op; -} diff --git a/FileSystem/Mounts/Teletype.cpp b/FileSystem/Mounts/Teletype.cpp deleted file mode 100644 index fb4894d7..00000000 --- a/FileSystem/Mounts/Teletype.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -ReadFSFunction(tty_Write) -{ - for (size_t i = 0; i < Size; i++) - putchar(((char *)Buffer)[i]); - - Display->SetBuffer(0); - return Size; -} - -FileSystemOperations tty_op = { - .Name = "tty", - .Write = tty_Write, -}; - -void Init_Teletype(Virtual *vfs_ctx) -{ - Node *n = vfs_ctx->Create("tty", CHARDEVICE, DevFS); - n->Operator = &tty_op; -} diff --git a/FileSystem/Mounts/Zero.cpp b/FileSystem/Mounts/Zero.cpp deleted file mode 100644 index b441e449..00000000 --- a/FileSystem/Mounts/Zero.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -ReadFSFunction(Zero_Read) -{ - if (Size <= 0) - return 0; - - memset(Buffer, 0, Size); - return Size; -} - -ReadFSFunction(Zero_Write) -{ - return Size; -} - -FileSystemOperations zero_op = { - .Name = "Zero", - .Read = Zero_Read, - .Write = Zero_Write, -}; - -void Init_Zero(Virtual *vfs_ctx) -{ - Node *n = vfs_ctx->Create("zero", CHARDEVICE, DevFS); - n->Operator = &zero_op; -} diff --git a/ISSUES.md b/ISSUES.md new file mode 100644 index 00000000..3820f993 --- /dev/null +++ b/ISSUES.md @@ -0,0 +1,7 @@ +- [x] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) +- [x] After setting the new stack pointer, the kernel crashes with an invalid opcode. +- [ ] Somewhere in the kernel, the memory is wrongly freed or memcpy/memset. +- [ ] GlobalDescriptorTable::SetKernelStack() is not working properly. +- [ ] Sometimes while the kernel is inside BeforeShutdown(), we end up in a deadlock. +- [ ] CPU usage is not working properly. +- [x] fork() syscall is not working. diff --git a/Kernel.cpp b/Kernel.cpp deleted file mode 100644 index 06a6c1f8..00000000 --- a/Kernel.cpp +++ /dev/null @@ -1,740 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "kernel.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Core/smbios.hpp" -#include "Tests/t.h" - -bool DebuggerIsAttached = false; - -/** - * Fennix Kernel - * ------------- - * This is the main kernel file. It contains the main function and the kernel entry point. - * - * LOADING PROCEDURE: - * [BOOT] -> [Bootloader] -> [Boot Info Parser] -> Entry() -> Main() -> KernelMainThread() - * - Bootloader - * - Entry() is the first function to be called by the boot info parser function after getting the boot info from the bootloader. - * - Main() is the first function to be called by Entry(). - * - KernelMainThread() is the first function to be called by the task manager. - * - * TODO: - * - [x] Optimize SMP. - * - [ ] Support IPv6. - * - [ ] Endianess of the network stack (currently: [HOST](LSB)<=>[NETWORK](MSB)). Not sure if this is a standard or not. - * - [ ] Support 32-bit applications (ELF, PE, etc). - * - [ ] Do not map the entire memory. Map only the needed memory address at allocation time. - * - [ ] Implementation of logging (beside serial) with log rotation. - * - [ ] Implement a better task manager. (replace struct P/TCB with classes) - * - [?] Rewrite virtual file system. (it's very bad, I don't know how I wrote it this bad) - * - [ ] Colors in crash screen are not following the kernel color scheme. - * - [x] Find a way to add intrinsics. - * - [ ] Rework PSF1 font loader. - * - [x] The cleanup should be done by a thread (tasking). This is done to avoid a deadlock. - * - [ ] Implement a better Display::SetBrightness() function. - * - [ ] Fix memcpy, memset and memcmp functions (they are not working properly with SIMD). - * - [ ] Fully support i386. - * - [ ] Support Aarch64. - * - [ ] SMP trampoline shouldn't be hardcoded at 0x2000. - * - [ ] Rework the stack guard. - * - [x] Mutex implementation. - * - [ ] Update SMBIOS functions to support newer versions and actually use it. - * - [ ] COW (Copy On Write) for the virtual memory. (https://en.wikipedia.org/wiki/Copy-on-write) - * - [ ] Bootstrap should have a separate bss section + PHDR. - * - [ ] Reimplement the driver conflict detection. - * - [ ] Elf loader shouldn't create a full copy of the elf binary. Copy only the needed sections. - * - [ ] Use NX-bit. - * - * ISSUES: - * - [x] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) - * - [x] After setting the new stack pointer, the kernel crashes with an invalid opcode. - * - [?] Somewhere in the kernel, the memory is wrongly freed or memcpy/memset. - * - [ ] GlobalDescriptorTable::SetKernelStack() is not working properly. - * - [ ] Sometimes while the kernel is inside BeforeShutdown(), we end up in a deadlock. - * - [ ] CPU usage is not working properly. - * - [x] fork() syscall is not working. - * - * CREDITS AND REFERENCES: - * - General: - * https://wiki.osdev.org/Main_Page - * https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html#x86-Built-in-Functions - * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes - * - * - Font: - * http://www.fial.com/~scott/tamsyn-font/ - * - * - CPU XCR0 structure: - * https://wiki.osdev.org/CPU_Registers_x86#XCR0 - * - * - CPUID 0x7: - * https://en.wikipedia.org/wiki/CPUID - * - * - Network: - * https://web.archive.org/web/20051210132103/http://users.pcnet.ro/dmoroian/beej/Beej.html - * https://web.archive.org/web/20060229214053/http://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html - * https://en.wikipedia.org/wiki/EtherType - * https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-network-packet-reception - * https://linux-kernel-labs.github.io/refs/heads/master/labs/networking.html - * https://github.com/smoltcp-rs/smoltcp - * https://www.ciscopress.com/articles/article.asp?p=3089352&seqNum=5 - * https://www.cs.unh.edu/cnrg/people/gherrin/linux-net.html - * https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers - * https://github.com/TheUltimateFoxOS/horizon - * https://en.wikipedia.org/wiki/Address_Resolution_Protocol - * https://en.cppreference.com/w/cpp/language/operators - * https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol - * https://www.cs.usfca.edu/~cruse/cs326f04/RTL8139D_DataSheet.pdf - * https://www.javatpoint.com/arp-packet-format - * https://www.cs.usfca.edu/~cruse/cs326f04/RTL8139_ProgrammersGuide.pdf - * http://realtek.info/pdf/rtl8139cp.pdf - * https://en.wikipedia.org/wiki/IPv4 - * https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml - * - * - Loading ELF shared libraries and dynamic linking: - * https://www.akkadia.org/drepper/dsohowto.pdf - * https://wiki.osdev.org/Dynamic_Linker - * https://github.com/tyler569/nightingale - * https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html - * https://www.youtube.com/watch?v=kUk5pw4w0h4 - * https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html - * https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got - * - * - IPC: - * https://docs.oracle.com/cd/E19048-01/chorus5/806-6897/architecture-103/index.html - * https://www.scaler.com/topics/operating-system/inter-process-communication-in-os/ - * https://en.wikipedia.org/wiki/Inter-process_communication - * https://www.geeksforgeeks.org/inter-process-communication-ipc/ - * - * - PCI: - * https://wiki.osdev.org/PCI - * https://en.wikipedia.org/wiki/PCI_configuration_space - * - * - Audio: - * https://trac.ffmpeg.org/wiki/audio%20types - * https://wiki.osdev.org/AC97 - * https://github.com/LemonOSProject/LemonOS - * https://inst.eecs.berkeley.edu//~cs150/Documents/ac97_r23.pdf - * - * - Intrinsics: - * https://learn.microsoft.com/en-us/cpp/intrinsics/x86-intrinsics-list - * https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html - * - * - CPUID lists: - * https://www.amd.com/system/files/TechDocs/40332.pdf - * https://www.scss.tcd.ie/~jones/CS4021/processor-identification-cpuid-instruction-note.pdf - * - * - SMBIOS: - * https://www.dmtf.org/dsp/DSP0134 - * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf - * https://wiki.osdev.org/System_Management_BIOS - * - * - EDBA: - * https://wiki.osdev.org/Memory_Map_(x86) - * - * - UMIP, SMAP and SMEP: - * https://en.wikipedia.org/wiki/Control_register - * https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf - * https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention - * - * - Atomic operations: - * https://en.cppreference.com/w/cpp/atomic/atomic - * - * - ELF: - * https://www.sco.com/developers/gabi/latest/ch4.eheader.html - * https://refspecs.linuxfoundation.org/elf/elf.pdf - * https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html - * https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html - * https://www.youtube.com/watch?v=nC1U1LJQL8o - * https://stevens.netmeister.org/631/elf.html - * https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h - * - * - C++ ABI: - * https://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3 - * https://itanium-cxx-abi.github.io/cxx-abi/abi.html - * - * - Keyboard: - * https://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html - * https://wiki.osdev.org/PS/2_Keyboard - * - */ - -#ifdef a64 -#if UINTPTR_MAX != UINT64_MAX -#error "uintptr_t is not 64-bit!" -#endif // UINTPTR_MAX != UINT64_MAX -#endif // a64 - -#ifdef a32 -#if UINTPTR_MAX != UINT32_MAX -#error "uintptr_t is not 32-bit!" -#endif // UINTPTR_MAX != UINT32_MAX -#endif // a32 - -#ifdef aa64 -#if UINTPTR_MAX != UINT64_MAX -#error "uintptr_t is not 64-bit!" -#endif // UINTPTR_MAX != UINT64_MAX -#endif // aa64 - -NewLock(KernelLock); - -#include - -using VirtualFileSystem::Node; -using VirtualFileSystem::NodeFlags; - -__aligned(16) BootInfo bInfo{}; -Video::Display *Display = nullptr; -SymbolResolver::Symbols *KernelSymbolTable = nullptr; -Power::Power *PowerManager = nullptr; -PCI::PCI *PCIManager = nullptr; -Tasking::Task *TaskManager = nullptr; -Time::time *TimeManager = nullptr; -VirtualFileSystem::Virtual *vfs = nullptr; - -KernelConfig Config = { - .AllocatorType = Memory::MemoryAllocatorType::liballoc11, - .SchedulerType = Multi, - .DriverDirectory = {'/', 'm', 'o', 'd', 'u', 'l', 'e', 's', '\0'}, - .InitPath = {'/', 'b', 'i', 'n', '/', 'i', 'n', 'i', 't', '\0'}, - .UseLinuxSyscalls = false, - .InterruptsOnCrash = true, - .Cores = 0, - .IOAPICInterruptCore = 0, - .UnlockDeadLock = false, - .SIMD = false, - .BootAnimation = false, -}; - -extern bool EnableProfiler; - -// For the Display class. Printing on first buffer as default. -int PutCharBufferIndex = 0; -EXTERNC void putchar(char c) -{ - if (Display) - Display->Print(c, PutCharBufferIndex); - else - UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(c); -} - -EXTERNC void KPrint(const char *Format, ...) -{ - SmartLock(KernelLock); - - if (TimeManager) - { - uint64_t Nanoseconds = TimeManager->GetNanosecondsSinceClassCreation(); - if (Nanoseconds != 0) - { -#if defined(a64) - printf("\eCCCCCC[\e00AEFF%lu.%07lu\eCCCCCC] ", - Nanoseconds / 10000000, Nanoseconds % 10000000); -#elif defined(a32) - printf("\eCCCCCC[\e00AEFF%llu.%07llu\eCCCCCC] ", - Nanoseconds / 10000000, Nanoseconds % 10000000); -#elif defined(aa64) - printf("\eCCCCCC[\e00AEFF%lu.%07lu\eCCCCCC] ", - Nanoseconds / 10000000, Nanoseconds % 10000000); -#endif - } - } - - va_list args; - va_start(args, Format); - vprintf(Format, args); - va_end(args); - - printf("\eCCCCCC\n"); - if (!Config.BootAnimation && Display) - Display->SetBuffer(0); -} - -EXTERNC NIF void Main() -{ - Display = new Video::Display(bInfo.Framebuffer[0]); - - KPrint("%s - %s [\e058C19%s\eFFFFFF]", - KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); - KPrint("CPU: \e058C19%s \e8822AA%s \e8888FF%s", - CPU::Hypervisor(), CPU::Vendor(), CPU::Name()); - - if (Display->GetFramebufferStruct().BitsPerPixel != 32) - KPrint("\eFF5500Framebuffer is not 32 bpp. This may cause issues."); - - debug("CPU: %s %s %s", - CPU::Hypervisor(), CPU::Vendor(), CPU::Name()); - - if (DebuggerIsAttached) - KPrint("\eFFA500Kernel debugger detected."); - -#if defined(a86) && defined(DEBUG) - uint8_t lpt1 = inb(0x378); - uint8_t lpt2 = inb(0x278); - uint8_t lpt3 = inb(0x3BC); - - uint8_t com1 = inb(0x3F8); - uint8_t com2 = inb(0x2F8); - uint8_t com3 = inb(0x3E8); - uint8_t com4 = inb(0x2E8); - - if (lpt1 != 0xFF) - KPrint("LPT1 is present."); - - if (lpt2 != 0xFF) - KPrint("LPT2 is present."); - - if (lpt3 != 0xFF) - KPrint("LPT3 is present."); - - if (com1 != 0xFF) - KPrint("COM1 is present."); - - if (com2 != 0xFF) - KPrint("COM2 is present."); - - if (com3 != 0xFF) - KPrint("COM3 is present."); - - if (com4 != 0xFF) - KPrint("COM4 is present."); - - KPrint("Display: %dx%d %d bpp \eFF0000R:%d %d \e00FF00G: %d %d \e0000FFB: %d %d", - Display->GetFramebufferStruct().Width, - Display->GetFramebufferStruct().Height, - Display->GetFramebufferStruct().BitsPerPixel, - Display->GetFramebufferStruct().RedMaskSize, - Display->GetFramebufferStruct().RedMaskShift, - Display->GetFramebufferStruct().GreenMaskSize, - Display->GetFramebufferStruct().GreenMaskShift, - Display->GetFramebufferStruct().BlueMaskSize, - Display->GetFramebufferStruct().BlueMaskShift); -#endif - - /**************************************************************************************/ - - KPrint("Reading Kernel Parameters"); - ParseConfig((char *)bInfo.Kernel.CommandLine, &Config); - - KPrint("Initializing CPU Features"); - CPU::InitializeFeatures(0); - - KPrint("Initializing GDT and IDT"); - Interrupts::Initialize(0); - - KPrint("Loading Kernel Symbols"); - KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)bInfo.Kernel.FileBase); - - if (!KernelSymbolTable->SymTableExists) - KernelSymbolTable->AddSymbolInfoFromGRUB(bInfo.Kernel.Symbols.Num, - bInfo.Kernel.Symbols.EntSize, - bInfo.Kernel.Symbols.Shndx, - bInfo.Kernel.Symbols.Sections); - - if (Config.BootAnimation) - { - Display->CreateBuffer(0, 0, 1); - - Display->SetDoNotScroll(true, 1); - Video::ScreenBuffer *buf = Display->GetBuffer(1); - Video::FontInfo fi = Display->GetCurrentFont()->GetInfo(); - Display->SetBufferCursor(1, 0, buf->Height - fi.Height); - PutCharBufferIndex = 1; - printf("Fennix Operating System - %s [\e058C19%s\eFFFFFF]\n", - KERNEL_VERSION, GIT_COMMIT_SHORT); - Display->SetBuffer(1); - PutCharBufferIndex = 0; - } - - KPrint("Initializing Power Manager"); - PowerManager = new Power::Power; - - KPrint("Enabling Interrupts on Bootstrap Processor"); - Interrupts::Enable(0); - -#if defined(a86) - PowerManager->InitDSDT(); -#elif defined(aa64) -#endif - - KPrint("Initializing Timers"); - TimeManager = new Time::time; - TimeManager->FindTimers(PowerManager->GetACPI()); - - KPrint("Initializing PCI Manager"); - PCIManager = new PCI::PCI; - - foreach (auto Device in PCIManager->GetDevices()) - { - KPrint("PCI: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", - PCI::Descriptors::GetVendorName(Device->VendorID), - PCI::Descriptors::GetDeviceName(Device->VendorID, Device->DeviceID), - PCI::Descriptors::DeviceClasses[Device->Class], - PCI::Descriptors::GetSubclassName(Device->Class, Device->Subclass), - PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF)); - } - - KPrint("Initializing Bootstrap Processor Timer"); - Interrupts::InitializeTimer(0); - - KPrint("Initializing SMP"); - SMP::Initialize(PowerManager->GetMADT()); - - if (SMBIOS::CheckSMBIOS()) - { - SMBIOS::SMBIOSEntryPoint *smbios = SMBIOS::GetSMBIOSEntryPoint(); - SMBIOS::SMBIOSBIOSInformation *bios = SMBIOS::GetBIOSInformation(); - SMBIOS::SMBIOSSystemInformation *system = SMBIOS::GetSystemInformation(); - SMBIOS::SMBIOSBaseBoardInformation *baseboard = SMBIOS::GetBaseBoardInformation(); - - debug("SMBIOS: %p", smbios); - debug("BIOS: %p", bios); - debug("System: %p", system); - debug("Baseboard: %p", baseboard); - - if (smbios) - KPrint("SMBIOS: \eCCCCCCString:\e8888FF%.4s \eCCCCCCVersion (Major Minor):\e8888FF%d %d \eCCCCCCTable:\e8888FF%#x \eCCCCCCLength:\e8888FF%d", - smbios->EntryPointString, smbios->MajorVersion, smbios->MinorVersion, - smbios->TableAddress, smbios->TableLength); - else - KPrint("SMBIOS: \e8888FFSMBIOS found but not supported?"); - - if (bios) - { - const char *BIOSVendor = bios->GetString(bios->Vendor); - const char *BIOSVersion = bios->GetString(bios->Version); - const char *BIOSReleaseDate = bios->GetString(bios->ReleaseDate); - debug("%d %d %d", bios->Vendor, bios->Version, bios->ReleaseDate); - KPrint("BIOS: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", - BIOSVendor, BIOSVersion, BIOSReleaseDate); - } - - if (system) - { - const char *SystemManufacturer = system->GetString(system->Manufacturer); - const char *SystemProductName = system->GetString(system->ProductName); - const char *SystemVersion = system->GetString(system->Version); - const char *SystemSerialNumber = system->GetString(system->SerialNumber); - const char *SystemSKU = system->GetString(system->SKU); - const char *SystemFamily = system->GetString(system->Family); - debug("%d %d %d %d %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c %d %d", system->Manufacturer, system->ProductName, system->Version, - system->SerialNumber, - system->UUID[0], system->UUID[1], system->UUID[2], system->UUID[3], - system->UUID[4], system->UUID[5], system->UUID[6], system->UUID[7], - system->UUID[8], system->UUID[9], system->UUID[10], system->UUID[11], - system->UUID[12], system->UUID[13], system->UUID[14], system->UUID[15], - system->SKU, system->Family); - KPrint("System: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", - SystemManufacturer, SystemProductName, SystemVersion, SystemSerialNumber, SystemSKU, SystemFamily); - } - - if (baseboard) - { - const char *Manufacturer = baseboard->GetString(baseboard->Manufacturer); - const char *Product = baseboard->GetString(baseboard->Product); - const char *Version = baseboard->GetString(baseboard->Version); - const char *SerialNumber = baseboard->GetString(baseboard->SerialNumber); - debug("%d %d %d %d", baseboard->Manufacturer, baseboard->Product, baseboard->Version, baseboard->SerialNumber); - KPrint("Baseboard: \eCCCCCC\e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", - Manufacturer, Product, Version, SerialNumber); - } - } - else - KPrint("SMBIOS: \eFF0000Not Found"); - - KPrint("Initializing Filesystem..."); - vfs = new VirtualFileSystem::Virtual; - - for (size_t i = 0; i < MAX_MODULES; i++) - { - if (!bInfo.Modules[i].Address) - continue; - - if (strcmp(bInfo.Modules[i].CommandLine, "initrd") == 0) - { - debug("Found initrd at %p", bInfo.Modules[i].Address); - static char initrd = 0; - if (!initrd++) - { - uintptr_t initrdAddress = (uintptr_t)bInfo.Modules[i].Address; - VirtualFileSystem::USTAR *ustar = new VirtualFileSystem::USTAR; - ustar->ReadArchive(initrdAddress, vfs); - } - } - } - - if (vfs->GetRootNode()->Children.size() == 0) - { - VirtualFileSystem::FileSystemOperations null_op = { - .Name = "null", - }; - - vfs->CreateRoot("/", &null_op); - } - - if (!vfs->PathExists("/dev")) - DevFS = vfs->Create("/dev", NodeFlags::DIRECTORY); - else - { - RefNode *dev = vfs->Open("/dev"); - if (dev->GetNode()->Flags != NodeFlags::DIRECTORY) - { - KPrint("\eE85230/dev is not a directory! Halting..."); - CPU::Stop(); - } - DevFS = dev->GetNode(); - delete dev; - } - - if (!vfs->PathExists("/mnt")) - MntFS = vfs->Create("/mnt", NodeFlags::DIRECTORY); - else - { - RefNode *mnt = vfs->Open("/mnt"); - if (mnt->GetNode()->Flags != NodeFlags::DIRECTORY) - { - KPrint("\eE85230/mnt is not a directory! Halting..."); - CPU::Stop(); - } - MntFS = mnt->GetNode(); - delete mnt; - } - - if (!vfs->PathExists("/proc")) - ProcFS = vfs->Create("/proc", NodeFlags::DIRECTORY); - else - { - RefNode *proc = vfs->Open("/proc", nullptr); - if (proc->GetNode()->Flags != NodeFlags::DIRECTORY) - { - KPrint("\eE85230/proc is not a directory! Halting..."); - CPU::Stop(); - } - ProcFS = proc->GetNode(); - delete proc; - } - - if (!vfs->PathExists("/var")) - VarLogFS = vfs->Create("/var", NodeFlags::DIRECTORY); - else - { - RefNode *var = vfs->Open("/var", nullptr); - if (var->GetNode()->Flags != NodeFlags::DIRECTORY) - { - KPrint("\eE85230/var is not a directory! Halting..."); - CPU::Stop(); - } - VarLogFS = var->GetNode(); - delete var; - - if (!vfs->PathExists("/var/log")) - VarLogFS = vfs->Create("/var/log", NodeFlags::DIRECTORY); - else - { - RefNode *var_log = vfs->Open("/var/log", nullptr); - if (var_log->GetNode()->Flags != NodeFlags::DIRECTORY) - { - KPrint("\eE85230/var/log is not a directory! Halting..."); - CPU::Stop(); - } - VarLogFS = var_log->GetNode(); - delete var_log; - } - } - - Init_Null(vfs); - Init_Random(vfs); - Init_Teletype(vfs); - Init_Zero(vfs); - - KPrint("\e058C19################################"); - TaskManager = new Tasking::Task(Tasking::IP(KernelMainThread)); - CPU::Halt(true); -} - -typedef void (*CallPtr)(void); -extern CallPtr __init_array_start[0], __init_array_end[0]; -extern CallPtr __fini_array_start[0], __fini_array_end[0]; - -EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info) -{ - trace("Hello, World!"); - - if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) - { - debug("\n\n----------------------------------------\nDEBUGGER DETECTED\n----------------------------------------\n\n"); - DebuggerIsAttached = true; - } - - memcpy(&bInfo, Info, sizeof(BootInfo)); - debug("BootInfo structure is at %p", &bInfo); - - // https://wiki.osdev.org/Calling_Global_Constructors - trace("There are %d constructors to call", __init_array_end - __init_array_start); - for (CallPtr *func = __init_array_start; func != __init_array_end; func++) - (*func)(); - -#ifdef a86 - if (!bInfo.SMBIOSPtr) - { - trace("SMBIOS was not provided by the bootloader. Trying to find it manually."); - for (uintptr_t i = 0xF0000; i < 0x100000; i += 16) - { - if (memcmp((void *)i, "_SM_", 4) == 0 || memcmp((void *)i, "_SM3_", 5) == 0) - { - bInfo.SMBIOSPtr = (void *)i; - trace("Found SMBIOS at %#lx", i); - } - } - } - - if (!bInfo.RSDP) - { - trace("RSDP was not provided by the bootloader. Trying to find it manually."); - /* FIXME: Not always shifting by 4 will work. */ - uintptr_t EBDABase = (uintptr_t)mminw((void *)0x40E) << 4; - - for (uintptr_t ptr = EBDABase; - ptr < 0x100000; /* 1MB */ - ptr += 16) - { - if (unlikely(ptr == EBDABase + 0x400)) - { - trace("EBDA is full. Trying to find RSDP in the BIOS area."); - break; - } - - BootInfo::RSDPInfo *rsdp = (BootInfo::RSDPInfo *)ptr; - if (memcmp(rsdp->Signature, "RSD PTR ", 8) == 0) - { - bInfo.RSDP = (BootInfo::RSDPInfo *)rsdp; - trace("Found RSDP at %#lx", rsdp); - } - } - - for (uintptr_t ptr = 0xE0000; - ptr < 0x100000; /* 1MB */ - ptr += 16) - { - BootInfo::RSDPInfo *rsdp = (BootInfo::RSDPInfo *)ptr; - if (memcmp(rsdp->Signature, "RSD PTR ", 8) == 0) - { - bInfo.RSDP = (BootInfo::RSDPInfo *)rsdp; - trace("Found RSDP at %#lx", rsdp); - } - } - } -#endif - - InitializeMemoryManagement(); - - void *KernelStackAddress = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); - uintptr_t KernelStack = (uintptr_t)KernelStackAddress + STACK_SIZE - 0x10; - debug("Kernel stack: %#lx-%#lx", KernelStackAddress, KernelStack); -#if defined(a64) - asmv("mov %0, %%rsp" - : - : "r"(KernelStack) - : "memory"); - asmv("mov $0, %rbp"); -#elif defined(a32) - asmv("mov %0, %%esp" - : - : "r"(KernelStack) - : "memory"); - asmv("mov $0, %ebp"); -#elif defined(aa64) -#warning "Kernel stack is not set!" -#endif - -#ifdef DEBUG - /* I had to do this because KernelAllocator - * is a global constructor but we need - * memory management to be initialized first. - */ - TestMemoryAllocation(); - TestString(); - Test_std(); -#endif - EnableProfiler = true; - Main(); -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" -extern "C" void __cxa_finalize(void *); -EXTERNC __no_stack_protector void BeforeShutdown(bool Reboot) -{ - UNUSED(Reboot); - /* TODO: Announce shutdown */ - - trace("\n\n\n#################### SYSTEM SHUTTING DOWN ####################\n\n"); - - if (NIManager) - delete NIManager, NIManager = nullptr; - - if (DiskManager) - delete DiskManager, DiskManager = nullptr; - - if (DriverManager) - delete DriverManager, DriverManager = nullptr; - - if (TaskManager && !TaskManager->IsPanic()) - { - TaskManager->SignalShutdown(); - delete TaskManager, TaskManager = nullptr; - } - - if (vfs) - delete vfs, vfs = nullptr; - - if (TimeManager) - delete TimeManager, TimeManager = nullptr; - - if (Display) - delete Display, Display = nullptr; - // PowerManager should not be called - - // https://wiki.osdev.org/Calling_Global_Constructors - debug("Calling destructors..."); - for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++) - (*func)(); - __cxa_finalize(nullptr); - debug("Done."); -} -#pragma GCC diagnostic pop - -EXTERNC void TaskingPanic() -{ - if (TaskManager) - TaskManager->Panic(); -} diff --git a/KernelShell/Commands/cat.cpp b/KernelShell/Commands/cat.cpp deleted file mode 100644 index 741df05c..00000000 --- a/KernelShell/Commands/cat.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -void cmd_cat(const char *args) -{ - if (args[0] == '\0') - return; - - Node *thisNode = vfs->GetNodeFromPath(args, thisProcess->CurrentWorkingDirectory); - if (thisNode == nullptr) - { - printf("cat: %s: No such file or directory\n", args); - return; - } - - if (thisNode->Flags != NodeFlags::FILE && - thisNode->Flags != NodeFlags::CHARDEVICE) - { - printf("cat: %s: Not a file\n", args); - return; - } - std::string path = vfs->GetPathFromNode(thisNode); - - int fd = fopen(path.c_str(), "r"); - struct stat st; - fstat(fd, &st); - - char *buffer = new char[st.st_size + 1]; - fread(fd, buffer, st.st_size); - printf("%s\n", buffer); - delete[] buffer; - fclose(fd); -} diff --git a/KernelShell/Commands/cd.cpp b/KernelShell/Commands/cd.cpp deleted file mode 100644 index 8fe4826c..00000000 --- a/KernelShell/Commands/cd.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -void cmd_cd(const char *args) -{ - if (args[0] == '\0') - return; - - Node *thisNode = vfs->GetNodeFromPath(args, thisProcess->CurrentWorkingDirectory); - - if (thisNode == nullptr) - { - printf("cd: %s: No such file or directory\n", args); - return; - } - - if (thisNode->Flags != NodeFlags::DIRECTORY) - { - printf("cd: %s: Not a directory\n", args); - return; - } - - thisProcess->CurrentWorkingDirectory = thisNode; -} diff --git a/KernelShell/Commands/echo.cpp b/KernelShell/Commands/echo.cpp deleted file mode 100644 index 66a77c3b..00000000 --- a/KernelShell/Commands/echo.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include "../../kernel.h" - -void cmd_echo(const char *args) -{ - printf("%s\n", args); -} diff --git a/KernelShell/Commands/exit.cpp b/KernelShell/Commands/exit.cpp deleted file mode 100644 index 3606114d..00000000 --- a/KernelShell/Commands/exit.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_exit(const char *) -{ - KernelShutdownThread(false); - // TaskManager->KillThread(thisThread, KILL_SUCCESS); - CPU::Halt(true); -} diff --git a/KernelShell/Commands/kill.cpp b/KernelShell/Commands/kill.cpp deleted file mode 100644 index 7541faac..00000000 --- a/KernelShell/Commands/kill.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_kill(const char *args) -{ - PID pid = atoi(args); - PCB *pcb = TaskManager->GetProcessByID(pid); - - if (pcb == nullptr) - { - printf("No process with PID %d\n", pid); - return; - } - TaskManager->KillProcess(pcb, KILL_BY_OTHER_PROCESS); -} diff --git a/KernelShell/Commands/killall.cpp b/KernelShell/Commands/killall.cpp deleted file mode 100644 index 2c00a801..00000000 --- a/KernelShell/Commands/killall.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_killall(const char *args) -{ - foreach (auto Proc in TaskManager->GetProcessList()) - { - if (strcmp(Proc->Name, args) == 0) - { - TaskManager->KillProcess(Proc, KILL_BY_OTHER_PROCESS); - } - } -} diff --git a/KernelShell/Commands/ls.cpp b/KernelShell/Commands/ls.cpp deleted file mode 100644 index 8344ab2e..00000000 --- a/KernelShell/Commands/ls.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -void cmd_ls(const char *args) -{ - if (args[0] == '\0') - { - Node *rootNode = thisProcess->CurrentWorkingDirectory; - - if (rootNode == nullptr) - rootNode = vfs->GetRootNode()->Children[0]; - - foreach (auto var in rootNode->Children) - printf("%s\n", var->Name); - } - else - { - Node *thisNode = vfs->GetNodeFromPath(args, thisProcess->CurrentWorkingDirectory); - - if (thisNode == nullptr) - { - printf("ls: %s: No such file or directory\n", args); - return; - } - - if (thisNode->Flags != NodeFlags::DIRECTORY) - { - printf("%s\n", thisNode->Name); - return; - } - - foreach (auto var in thisNode->Children) - printf("%s\n", var->Name); - } -} diff --git a/KernelShell/Commands/lsof.cpp b/KernelShell/Commands/lsof.cpp deleted file mode 100644 index c0ddf661..00000000 --- a/KernelShell/Commands/lsof.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include "../../kernel.h" - -void cmd_lsof(const char *) -{ - printf("PROCESS FD NAME\n"); - foreach (auto Proc in TaskManager->GetProcessList()) - { - if (!Proc) - continue; - - std::vector fds_array = - Proc->FileDescriptors->GetFileDescriptors(); - foreach (auto fd in fds_array) - printf("%s %d: %s\n", Proc->Name, fd.Descriptor, - fd.Handle->AbsolutePath.c_str()); - } -} diff --git a/KernelShell/Commands/lspci.cpp b/KernelShell/Commands/lspci.cpp deleted file mode 100644 index 677430fe..00000000 --- a/KernelShell/Commands/lspci.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -void cmd_lspci(const char *) -{ - foreach (auto Device in PCIManager->GetDevices()) - { - printf("%02x:%02x.%d: %s: %s %s %s\n", - // Device->Bus, - // Device->Device, - // Device->Function, - // FIXME - 0, 0, 0, - PCI::Descriptors::BridgeDeviceSubclassName(Device->Subclass), - PCI::Descriptors::GetVendorName(Device->VendorID), - PCI::Descriptors::GetDeviceName(Device->VendorID, Device->DeviceID), - PCI::Descriptors::GetSubclassName(Device->Class, Device->Subclass)); - } -} diff --git a/KernelShell/Commands/ps.cpp b/KernelShell/Commands/ps.cpp deleted file mode 100644 index d738021e..00000000 --- a/KernelShell/Commands/ps.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_ps(const char *) -{ - printf("PID Name\n"); - foreach (auto p in TaskManager->GetProcessList()) - printf("%d %s\n", p->ID, p->Name); -} diff --git a/KernelShell/Commands/reboot.cpp b/KernelShell/Commands/reboot.cpp deleted file mode 100644 index a2c87662..00000000 --- a/KernelShell/Commands/reboot.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_reboot(const char *) -{ - KernelShutdownThread(true); - CPU::Halt(true); -} diff --git a/KernelShell/Commands/shutdown.cpp b/KernelShell/Commands/shutdown.cpp deleted file mode 100644 index 2e72275b..00000000 --- a/KernelShell/Commands/shutdown.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_shutdown(const char *) -{ - KernelShutdownThread(false); - CPU::Halt(true); -} diff --git a/KernelShell/Commands/top.cpp b/KernelShell/Commands/top.cpp deleted file mode 100644 index 64ca4f05..00000000 --- a/KernelShell/Commands/top.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; -using namespace Tasking; - -void cmd_top(const char *) -{ - printf("\e9400A1PID \e9CA100Name \e00A15BState \eCCCCCCPriority Memory Usage CPU Usage\n"); - foreach (auto Proc in TaskManager->GetProcessList()) - { -#if defined(a64) - printf("\e9400A1%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %ld %ld\n", - Proc->ID, Proc->Name, Proc->Status == Running ? "Running" : "Stopped", - Proc->Info.Priority, Proc->Memory->GetAllocatedMemorySize(), - Proc->Info.UserTime + Proc->Info.KernelTime); -#elif defined(a32) - printf("\e9400A1%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %lld %lld\n", - Proc->ID, Proc->Name, Proc->Status == Running ? "Running" : "Stopped", - Proc->Info.Priority, Proc->Memory->GetAllocatedMemorySize(), - Proc->Info.UserTime + Proc->Info.KernelTime); -#endif - - foreach (auto Thrd in Proc->Threads) - { -#if defined(a64) - printf(" \eA80011%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %ld %ld\n", - Thrd->ID, Thrd->Name, Thrd->Status == Running ? "Running" : "Stopped", - Thrd->Info.Priority, Thrd->Memory->GetAllocatedMemorySize(), - Thrd->Info.UserTime + Thrd->Info.KernelTime); -#elif defined(a32) - printf(" \eA80011%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %lld %lld\n", - Thrd->ID, Thrd->Name, Thrd->Status == Running ? "Running" : "Stopped", - Thrd->Info.Priority, Thrd->Memory->GetAllocatedMemorySize(), - Thrd->Info.UserTime + Thrd->Info.KernelTime); -#endif - } - } -} diff --git a/KernelShell/Commands/whoami.cpp b/KernelShell/Commands/whoami.cpp deleted file mode 100644 index 0a07607e..00000000 --- a/KernelShell/Commands/whoami.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "../cmds.hpp" - -#include - -#include "../../kernel.h" - -using namespace VirtualFileSystem; - -void cmd_whoami(const char *) -{ - printf("kernel\n"); -} diff --git a/KernelThread.cpp b/KernelThread.cpp deleted file mode 100644 index a1de40e8..00000000 --- a/KernelThread.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "kernel.h" -#ifdef DEBUG -#include "Tests/t.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define STB_IMAGE_IMPLEMENTATION -#define STBI_NO_STDIO -#define STBI_NO_LINEAR -#define STBI_NO_THREAD_LOCALS -#define STBI_NO_HDR -#define STBI_ONLY_TGA -#include - -#include "DAPI.hpp" -#include "Fex.hpp" - -using VirtualFileSystem::Node; -using VirtualFileSystem::NodeFlags; - -Driver::Driver *DriverManager = nullptr; -Disk::Manager *DiskManager = nullptr; -NetworkInterfaceManager::NetworkInterface *NIManager = nullptr; -VirtualFileSystem::Node *DevFS = nullptr; -VirtualFileSystem::Node *MntFS = nullptr; -VirtualFileSystem::Node *ProcFS = nullptr; -VirtualFileSystem::Node *VarLogFS = nullptr; - -#ifdef DEBUG -void TreeFS(Node *node, int Depth) -{ - return; - foreach (auto Chld in node->Children) - { - printf("%*c %s\eFFFFFF\n", Depth, ' ', Chld->Name); - - if (!Config.BootAnimation) - Display->SetBuffer(0); - TaskManager->Sleep(100); - TreeFS(Chld, Depth + 1); - } -} - -const char *Statuses[] = { - "FF0000", /* Unknown */ - "AAFF00", /* Ready */ - "00AA00", /* Running */ - "FFAA00", /* Sleeping */ - "FFAA00", /* Blocked */ - "FF0088", /* Zombie */ - "FF0000", /* Terminated */ -}; - -const char *StatusesSign[] = { - "Unknown", - "Ready", - "Run", - "Sleep", - "Wait", - "Stop", - "Terminated", -}; - -const char *SuccessSourceStrings[] = { - "Unknown", - "GetNextAvailableThread", - "GetNextAvailableProcess", - "SchedulerSearchProcessThread", -}; - -void TaskMgr_Dummy100Usage() -{ - while (1) - ; -} - -void TaskMgr_Dummy0Usage() -{ - while (1) - TaskManager->Sleep(1000000); -} - -uint64_t GetUsage(uint64_t OldSystemTime, Tasking::TaskInfo *Info) -{ - /* https://github.com/reactos/reactos/blob/560671a784c1e0e0aa7590df5e0598c1e2f41f5a/base/applications/taskmgr/perfdata.c#L347 */ - if (Info->OldKernelTime || Info->OldUserTime) - { - uint64_t SystemTime = TimeManager->GetCounter() - OldSystemTime; - uint64_t CurrentTime = Info->KernelTime + Info->UserTime; - uint64_t OldTime = Info->OldKernelTime + Info->OldUserTime; - uint64_t CpuUsage = (CurrentTime - OldTime) / SystemTime; - CpuUsage = CpuUsage * 100; - - // debug("CurrentTime: %ld OldTime: %ld Time Diff: %ld Usage: %ld%%", - // CurrentTime, OldTime, SystemTime, CpuUsage); - - Info->OldKernelTime = Info->KernelTime; - Info->OldUserTime = Info->UserTime; - return CpuUsage; - } - Info->OldKernelTime = Info->KernelTime; - Info->OldUserTime = Info->UserTime; - return 0; -} - -static int ShowTaskManager = 0; - -void TaskMgr() -{ - thisThread->Rename("Debug Task Manager"); - thisThread->SetPriority(Tasking::Idle); - - while (ShowTaskManager == 0) - CPU::Pause(); - - thisThread->SetPriority(Tasking::Idle); - - TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy100Usage))->Rename("Dummy 100% Usage"); - TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy0Usage))->Rename("Dummy 0% Usage"); - - while (true) - { - while (ShowTaskManager == 0) - CPU::Pause(); - - static int sanity = 0; - Video::ScreenBuffer *sb = Display->GetBuffer(0); - for (short i = 0; i < 1000; i++) - { - for (short j = 0; j < 500; j++) - { - uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); - *Pixel = 0x222222; - } - } - - uint32_t tmpX, tmpY; - Display->GetBufferCursor(0, &tmpX, &tmpY); - Display->SetBufferCursor(0, 0, 0); - printf("\eF02C21Task Manager\n"); - static uint64_t OldSystemTime = 0; - foreach (auto Proc in TaskManager->GetProcessList()) - { - if (!Proc) - continue; - int Status = Proc->Status.load(); - uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info); -#if defined(a64) - printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n", - Statuses[Status], Proc->Name, StatusesSign[Status], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime); -#elif defined(a32) - printf("\e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld)\n", - Statuses[Status], Proc->Name, StatusesSign[Status], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime); -#elif defined(aa64) -#endif - - foreach (auto Thd in Proc->Threads) - { - if (!Thd) - continue; - Status = Thd->Status.load(); - uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info); -#if defined(a64) - printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC", - Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, - Thd->Info.UserTime, Thd->Registers.rip, - Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.rip) : "unknown"); -#elif defined(a32) - printf(" \e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld, IP: \e24FF2B%#x \eEDFF24%s\e00AAAA)\n\eAABBCC", - Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, - Thd->Info.UserTime, Thd->Registers.eip, - Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.eip) : "unknown"); -#elif defined(aa64) -#endif - } - } - OldSystemTime = TimeManager->GetCounter(); -#if defined(a64) - register uintptr_t CurrentStackAddress asm("rsp"); - printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); -#elif defined(a32) - register uintptr_t CurrentStackAddress asm("esp"); - printf("Sanity: %d, Stack: %#x", sanity++, CurrentStackAddress); -#elif defined(aa64) - register uintptr_t CurrentStackAddress asm("sp"); - printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); -#endif - if (sanity > 1000) - sanity = 0; - Display->SetBufferCursor(0, tmpX, tmpY); - if (!Config.BootAnimation) - Display->SetBuffer(0); - - TaskManager->Sleep(100); - } -} - -static int ShowOpenFiles = 0; - -void lsof() -{ - thisThread->Rename("Debug File List"); - thisThread->SetPriority(Tasking::Idle); - - while (ShowOpenFiles == 0) - CPU::Pause(); - - thisThread->SetPriority(Tasking::High); - - vfs->Create("/dummy_lsof_file", NodeFlags::FILE); - fopen("/dummy_lsof_file", "r"); - - while (true) - { - while (ShowOpenFiles == 0) - CPU::Pause(); - - Video::ScreenBuffer *sb = Display->GetBuffer(0); - for (short i = 0; i < 500; i++) - { - for (short j = 0; j < 500; j++) - { - uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); - *Pixel = 0x222222; - } - } - - uint32_t tmpX, tmpY; - Display->GetBufferCursor(0, &tmpX, &tmpY); - Display->SetBufferCursor(0, 0, 0); - printf("\eF02C21Open Files (%ld):\e00AAAA\n", - TaskManager->GetProcessList().size()); - foreach (auto Proc in TaskManager->GetProcessList()) - { - if (!Proc) - continue; - - printf("%s:\n", Proc->Name); - - std::vector fds_array = - Proc->FileDescriptors->GetFileDescriptors(); - foreach (auto fd in fds_array) - printf(" %d: %s\n", fd.Descriptor, fd.Handle->AbsolutePath.c_str()); - } - Display->SetBufferCursor(0, tmpX, tmpY); - if (!Config.BootAnimation) - Display->SetBuffer(0); - } -} - -#include -std::mutex test_mutex; - -void mutex_test_long() -{ - while (true) - { - test_mutex.lock(); - debug("Long Thread %d got mutex", - thisThread->ID); - // TaskManager->Sleep(2000); - test_mutex.unlock(); - } -} - -void mutex_test() -{ - while (true) - { - test_mutex.lock(); - debug("Thread %d got mutex", - thisThread->ID); - // TaskManager->Sleep(200); - test_mutex.unlock(); - } -} - -BootInfo::FramebufferInfo fb_ptr{}; -void tasking_test_fb_loop(int x, int y, uint32_t color) -{ - assert(fb_ptr.BaseAddress != nullptr); - while (true) - { - for (int i = 0; i < 16; i++) - { - uint32_t *Pixel = (uint32_t *)((uintptr_t)fb_ptr.BaseAddress + - ((y + i) * fb_ptr.Width + x) * - (fb_ptr.BitsPerPixel / 8)); - for (int j = 0; j < 16; j++) - { - *Pixel = color; - Pixel++; - } - } - } -} - -void TTfbL_red() { tasking_test_fb_loop(0, 0, 0xFFFF0000); } -void TTfbL_green() { tasking_test_fb_loop(16, 0, 0xFF00FF00); } -void TTfbL_blue() { tasking_test_fb_loop(32, 0, 0xFF0000FF); } -void TTfbL_white() { tasking_test_fb_loop(48, 0, 0xFFFFFFFF); } -void TTfbL_gray() { tasking_test_fb_loop(64, 0, 0xFF888888); } -void TTfbL_red_neg() { tasking_test_fb_loop(0, 0, 0xFF00FFFF); } -void TTfbL_green_neg() { tasking_test_fb_loop(16, 0, 0xFFFF00FF); } -void TTfbL_blue_neg() { tasking_test_fb_loop(32, 0, 0xFFFFFF00); } -void TTfbL_white_neg() { tasking_test_fb_loop(48, 0, 0xFF000000); } -void TTfbL_gray_neg() { tasking_test_fb_loop(64, 0, 0xFF777777); } -void TTfbL_rainbow_fct(int offset) -{ - while (true) - { - /* AARRGGBB*/ - static uint32_t color = 0xFF000000; - - for (int i = 0; i < 64; i++) - { - uint32_t *Pixel = (uint32_t *)((uintptr_t)fb_ptr.BaseAddress + - ((offset + i) * fb_ptr.Width) * - (fb_ptr.BitsPerPixel / 8)); - for (int j = 0; j < 16; j++) - { - *Pixel = color; - Pixel++; - } - } - if (color >= 0xFFFFFFFF) - color = 0xFF000000; - color++; - } -} -void TTfbL_rainbow_idle() { TTfbL_rainbow_fct(16); } -void TTfbL_rainbow_low() { TTfbL_rainbow_fct(80); } -void TTfbL_rainbow_norm() { TTfbL_rainbow_fct(144); } -void TTfbL_rainbow_high() { TTfbL_rainbow_fct(208); } -void TTfbL_rainbow_crit() { TTfbL_rainbow_fct(272); } -void tasking_test_fb() -{ - fb_ptr = Display->GetFramebufferStruct(); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_red)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_green)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_blue)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_white)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_gray)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_red_neg)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_green_neg)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_blue_neg)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_white_neg)); - TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_gray_neg)); - - { - CriticalSection cs; /* Start all threads at the same time */ - auto tti = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_idle)); - auto ttl = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_low)); - auto ttn = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_norm)); - auto tth = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_high)); - auto ttc = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_crit)); - - tti->SetPriority(Tasking::TaskPriority::Idle); - ttl->SetPriority(Tasking::TaskPriority::Low); - ttn->SetPriority(Tasking::TaskPriority::Normal); - tth->SetPriority(Tasking::TaskPriority::High); - ttc->SetPriority(Tasking::TaskPriority::Critical); - } - // Exit -} -#endif - -int SpawnInit() -{ - const char *envp[5] = { - "PATH=/bin:/usr/bin", - "TERM=tty", - "HOME=/root", - "USER=root", - nullptr}; - - const char *argv[4] = { - Config.InitPath, - "--init", - "--critical", - nullptr}; - - return Execute::Spawn(Config.InitPath, argv, envp, - nullptr, - Tasking::TaskCompatibility::Native, - true); -} - -/* Files: 0.tga 1.tga ... 26.tga */ -uint8_t *Frames[27]; -uint32_t FrameSizes[27]; -size_t FrameCount = 1; - -void BootLogoAnimationThread() -{ - char BootAnimPath[16]; - while (FrameCount < 27) - { - sprintf(BootAnimPath, "/etc/boot/%ld.tga", FrameCount); - RefNode *frame = vfs->Open(BootAnimPath); - if (!frame) - { - debug("Failed to load boot animation frame %s", BootAnimPath); - break; - } - - FrameSizes[FrameCount] = s_cst(uint32_t, frame->Length); - Frames[FrameCount] = new uint8_t[frame->Length]; - frame->Read(Frames[FrameCount], frame->Length); - delete frame; - FrameCount++; - } - - uint32_t DispX = Display->GetBuffer(1)->Width; - uint32_t DispY = Display->GetBuffer(1)->Height; - - for (size_t i = 1; i < FrameCount; i++) - { - int x, y, channels; - - if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], - &x, &y, &channels)) - continue; - - uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], - FrameSizes[i], &x, &y, - &channels, STBI_rgb_alpha); - - if (img == NULL) - continue; - - int offsetX = DispX / 2 - x / 2; - int offsetY = DispY / 2 - y / 2; - - for (int i = 0; i < x * y; i++) - { - uint32_t pixel = ((uint32_t *)img)[i]; - int r = (pixel >> 16) & 0xFF; - int g = (pixel >> 8) & 0xFF; - int b = (pixel >> 0) & 0xFF; - int a = (pixel >> 24) & 0xFF; - - if (a != 0xFF) - { - r = (r * a) / 0xFF; - g = (g * a) / 0xFF; - b = (b * a) / 0xFF; - } - - Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, - (r << 16) | (g << 8) | (b << 0), 1); - } - - free(img); - Display->SetBuffer(1); - TaskManager->Sleep(50); - } - - int brightness = 100; - while (brightness >= 0) - { - brightness -= 10; - Display->SetBrightness(brightness, 1); - Display->SetBuffer(1); - TaskManager->Sleep(5); - } -} - -void ExitLogoAnimationThread() -{ - Display->SetBrightness(100, 1); - Display->SetBuffer(1); - - /* Files: 26.tga 25.tga ... 1.tga */ - uint32_t DispX = Display->GetBuffer(1)->Width; - uint32_t DispY = Display->GetBuffer(1)->Height; - - for (size_t i = FrameCount - 1; i > 0; i--) - { - int x, y, channels; - - if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], - &x, &y, &channels)) - continue; - - uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], - FrameSizes[i], &x, &y, - &channels, STBI_rgb_alpha); - - if (img == NULL) - continue; - - int offsetX = DispX / 2 - x / 2; - int offsetY = DispY / 2 - y / 2; - - for (int i = 0; i < x * y; i++) - { - uint32_t pixel = ((uint32_t *)img)[i]; - int r = (pixel >> 16) & 0xFF; - int g = (pixel >> 8) & 0xFF; - int b = (pixel >> 0) & 0xFF; - int a = (pixel >> 24) & 0xFF; - - if (a != 0xFF) - { - r = (r * a) / 0xFF; - g = (g * a) / 0xFF; - b = (b * a) / 0xFF; - } - - Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, - (r << 16) | (g << 8) | (b << 0), 1); - } - - free(img); - Display->SetBuffer(1); - TaskManager->Sleep(50); - } - - int brightness = 100; - while (brightness >= 0) - { - brightness -= 10; - Display->SetBrightness(brightness, 1); - Display->SetBuffer(1); - TaskManager->Sleep(5); - } -} - -void CleanupProcessesThreadWrapper() -{ - TaskManager->CleanupProcessesThread(); -} - -void KernelMainThread() -{ - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test_long)); - // TaskManager->Yield(); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); - // ilp; - - // TaskManager->CreateThread(thisProcess, Tasking::IP(tasking_test_fb)); - // ilp; - - Tasking::TCB *clnThd = - TaskManager->CreateThread(thisProcess, - Tasking::IP(CleanupProcessesThreadWrapper)); - clnThd->SetPriority(Tasking::Idle); - TaskManager->SetCleanupThread(clnThd); - thisThread->SetPriority(Tasking::Critical); - - Tasking::TCB *blaThread = nullptr; - - if (Config.BootAnimation) - { - blaThread = - TaskManager->CreateThread(thisProcess, - Tasking::IP(BootLogoAnimationThread)); - blaThread->Rename("Logo Animation"); - } - -#ifdef DEBUG - TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr)); - TaskManager->CreateThread(thisProcess, Tasking::IP(lsof)); - TreeFS(vfs->GetRootNode(), 0); -#endif - - KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", - __DATE__, __TIME__, CPP_LANGUAGE_STANDARD); - KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus); - - if (IsVirtualizedEnvironment()) - KPrint("Running in Virtualized Environment"); - - KPrint("Initializing Disk Manager..."); - DiskManager = new Disk::Manager; - - KPrint("Loading Modules..."); - DriverManager = new Driver::Driver; - DriverManager->LoadDrivers(); - - KPrint("Fetching Disks..."); - if (DriverManager->GetDrivers().size() > 0) - { - foreach (auto Driver in DriverManager->GetDrivers()) - if (((FexExtended *)Driver.ExtendedHeaderAddress)->Driver.Type == FexDriverType::FexDriverType_Storage) - DiskManager->FetchDisks(Driver.DriverUID); - } - else - KPrint("\eE85230No disk drivers found! Cannot fetch disks!"); - - KPrint("Initializing Network Interface Manager..."); - NIManager = new NetworkInterfaceManager::NetworkInterface; - KPrint("Starting Network Interface Manager..."); - NIManager->StartService(); - - KPrint("Setting up userspace"); - int ExitCode = -1; - Tasking::TCB *initThread = nullptr; - int tid = SpawnInit(); - if (tid < 0) - { - KPrint("\eE85230Failed to start %s! Code: %d", Config.InitPath, tid); - goto Exit; - } - - KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath); - thisThread->SetPriority(Tasking::Idle); - - initThread = TaskManager->GetThreadByID(tid); - TaskManager->WaitForThread(initThread); - ExitCode = initThread->GetExitCode(); -Exit: - if (ExitCode == 0) - { - KPrint("\eFF7900%s process exited with code %d and it didn't invoked the shutdown function.", - Config.InitPath, ExitCode); - KPrint("System Halted"); - CPU::Halt(true); - } - - KPrint("\eE85230Userspace process exited with code %d (%#x)", - ExitCode, ExitCode < 0 ? -ExitCode : ExitCode); - KPrint("Dropping to kernel shell..."); - TaskManager->Sleep(1000); - TaskManager->WaitForThread(blaThread); - TaskManager->CreateThread(thisProcess, - Tasking::IP(KShellThread)) - ->Rename("Kernel Shell"); - CPU::Halt(true); -} - -NewLock(ShutdownLock); -void __no_stack_protector KernelShutdownThread(bool Reboot) -{ - SmartLock(ShutdownLock); - debug("KernelShutdownThread(%s)", Reboot ? "true" : "false"); - if (Config.BootAnimation && TaskManager) - { - Tasking::TCB *elaThread = - TaskManager->CreateThread(thisProcess, - Tasking::IP(ExitLogoAnimationThread)); - elaThread->Rename("Logo Animation"); - TaskManager->WaitForThread(elaThread); - } - - BeforeShutdown(Reboot); - - trace("%s...", Reboot ? "Rebooting" : "Shutting down"); - if (Reboot) - PowerManager->Reboot(); - else - PowerManager->Shutdown(); - CPU::Stop(); -} - -void KST_Reboot() { KernelShutdownThread(true); } -void KST_Shutdown() { KernelShutdownThread(false); } diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/LICENSES.md b/LICENSES.md new file mode 100644 index 00000000..88190c2b --- /dev/null +++ b/LICENSES.md @@ -0,0 +1,44 @@ +# Licenses in the project + +This project uses code from other projects, each with its own licenses. +Below are the licenses associated with these components. +Make sure to read and comply with these licenses before using or redistributing this software. + +## printf + +- **License:** The MIT License (MIT) +- **Location:** [library/printf.c](library/printf.c) [include/printf.h](include/printf.h) + +## stb_image + +- **License:** The MIT License (MIT) and Public Domain +- **Location:** [include/stb/image.h](include/stb/image.h) + +## stb_image_resize + +- **License:** The MIT License (MIT) and Public Domain +- **Location:** [include/stb/image_resize.h](include/stb/image_resize.h) + +## cargs + +- **License:** The MIT License (MIT) +- **Location:** [library/cargs.c](library/cargs.c) [include/cargs.h](include/cargs.h) + +## cwalk + +- **License:** The MIT License (MIT) +- **Location:** [library/cwalk.c](library/cwalk.c) [include/cwalk.h](include/cwalk.h) + +## Tamsyn Font (v1.11) + +- **License:** Unknown +- **Location:** [files/tamsyn-font-1.11/LICENSE](files/tamsyn-font-1.11/LICENSE) + +## liballoc + +- **License:** Public Domain +- **Location:** [https://raw.githubusercontent.com/blanham/liballoc/master/LICENSE](https://raw.githubusercontent.com/blanham/liballoc/master/LICENSE) + +... + +Please refer to the respective license files for the full text of each license. diff --git a/Library/Bitmap.cpp b/Library/Bitmap.cpp deleted file mode 100644 index 92e60c6a..00000000 --- a/Library/Bitmap.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -bool Bitmap::Get(uint64_t index) -{ - if (index > Size * 8) - return false; - - uint64_t byteIndex = index / 8; - uint8_t bitIndex = index % 8; - uint8_t bitIndexer = 0b10000000 >> bitIndex; - - if ((Buffer[byteIndex] & bitIndexer) > 0) - return true; - - return false; -} - -bool Bitmap::Set(uint64_t index, bool value) -{ - if (index > Size * 8) - return false; - - uint64_t byteIndex = index / 8; - uint8_t bitIndex = index % 8; - uint8_t bitIndexer = 0b10000000 >> bitIndex; - - Buffer[byteIndex] &= ~bitIndexer; - if (value) - Buffer[byteIndex] |= bitIndexer; - - return true; -} - -bool Bitmap::operator[](uint64_t index) { return this->Get(index); } diff --git a/Library/libstdc++/fundamental_type_info.cpp b/Library/libstdc++/fundamental_type_info.cpp deleted file mode 100644 index e4ab1a9f..00000000 --- a/Library/libstdc++/fundamental_type_info.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -namespace __cxxabiv1 -{ - __fundamental_type_info::~__fundamental_type_info() {} -} diff --git a/Library/libstdc++/pointer_type_info.cpp b/Library/libstdc++/pointer_type_info.cpp deleted file mode 100644 index 622ac2d0..00000000 --- a/Library/libstdc++/pointer_type_info.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -namespace __cxxabiv1 -{ - __pointer_type_info::~__pointer_type_info() {} - - bool __pointer_type_info::__is_pointer_p() const { return true; } - - bool __pointer_type_info::__pointer_catch(const __pbase_type_info *ThrownType, - void **ThrowObject, - unsigned Outer) const - { -#ifndef __GXX_RTTI - UNUSED(ThrownType); - UNUSED(ThrowObject); - UNUSED(Outer); - return false; -#else - if (Outer < 2 && *this->Pointee == typeid(void)) - return !ThrownType->Pointee->__is_function_p(); - - return __pbase_type_info::__pointer_catch(ThrownType, - ThrowObject, - Outer); -#endif - } - -} diff --git a/Library/libstdc++/unwind.cpp b/Library/libstdc++/unwind.cpp deleted file mode 100644 index 6d0ce80c..00000000 --- a/Library/libstdc++/unwind.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include -#include -#include - -#include "../../kernel.h" - -using namespace __cxxabiv1; - -#if (1) /* Stubs if libgcc is not present */ -extern "C" _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *Exception) -{ - fixme("_Unwind_RaiseException( %p ) called.", Exception); - error("Unhandled exception."); - return _URC_FATAL_PHASE1_ERROR; - // return _URC_NO_REASON; -} - -extern "C" void _Unwind_Resume(struct _Unwind_Exception *Exception) -{ - fixme("_Unwind_Resume( %p ) called.", Exception); -} -#endif diff --git a/Library/std/errno.cpp b/Library/std/errno.cpp deleted file mode 100644 index 5a17ab2e..00000000 --- a/Library/std/errno.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include -#include - -#include "../../kernel.h" - -__aligned(16) static int errno_value = 0; - -int *__errno_location(void) -{ - if (unlikely(!TaskManager || !thisThread)) - return &errno_value; - return &thisThread->ErrorNumber; -} diff --git a/Library/std/typeinfo.cpp b/Library/std/typeinfo.cpp deleted file mode 100644 index 8d8dd54d..00000000 --- a/Library/std/typeinfo.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -namespace std -{ - type_info::~type_info() {} - - bool type_info::__do_catch(const type_info *ThrowType, - void **ThrowObject, - unsigned Outer) const - { - stub; - UNUSED(ThrowType); - UNUSED(ThrowObject); - UNUSED(Outer); - return false; - } - - bool type_info::__do_upcast(const __cxxabiv1::__class_type_info *Target, - void **ObjectPointer) const - { - stub; - UNUSED(Target); - UNUSED(ObjectPointer); - return false; - } -} diff --git a/Makefile b/Makefile index f15df7ec..6a0e6bf8 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ OBJCOPY = ../$(COMPILER_PATH)/$(COMPILER_ARCH)objcopy OBJDUMP = ../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump GDB = ../$(COMPILER_PATH)/$(COMPILER_ARCH)gdb -RUST_TARGET_PATH = Architecture/$(OSARCH)/rust-target.json +RUST_TARGET_PATH = arch/$(OSARCH)/rust-target.json GIT_COMMIT = $(shell git rev-parse HEAD) GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD) @@ -20,20 +20,20 @@ GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD) BMP_SOURCES = $(shell find ./ -type f -name '*.bmp') PSF_SOURCES = $(shell find ./ -type f -name '*.psf') ifeq ($(OSARCH), amd64) -S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") -s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") -C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") -CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") +S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*") +s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*") +C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*") +CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*") else ifeq ($(OSARCH), i386) -S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") -s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") -C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") -CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") +S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*") +s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*") +C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*") +CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*") else ifeq ($(OSARCH), aarch64) -S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") -s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") -C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") -CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") +S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./arch/amd64/*" -not -path "./arch/i386/*") +s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./arch/amd64/*" -not -path "./arch/i386/*") +C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./arch/amd64/*" -not -path "./arch/i386/*") +CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./arch/amd64/*" -not -path "./arch/i386/*") endif HEADERS = $(sort $(dir $(wildcard ./include/*))) $(sort $(dir $(wildcard ./include_std/*))) OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(s_SOURCES:.s=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o) @@ -66,7 +66,7 @@ ifeq ($(OSARCH), amd64) CFLAGS += -fno-pic -fno-pie -mno-red-zone -march=core2 \ -mcmodel=kernel -fno-builtin -Da64 -Da86 -m64 CFLAG_STACK_PROTECTOR := -fstack-protector-all -LDFLAGS += -TArchitecture/amd64/linker.ld \ +LDFLAGS += -Tarch/amd64/linker.ld \ -fno-pic -fno-pie \ -Wl,-static,--no-dynamic-linker,-ztext \ -zmax-page-size=0x1000 \ @@ -77,7 +77,7 @@ else ifeq ($(OSARCH), i386) CFLAGS += -fno-pic -fno-pie -mno-red-zone -march=pentium \ -fno-builtin -Da32 -Da86 -m32 CFLAG_STACK_PROTECTOR := -fstack-protector-all -LDFLAGS += -TArchitecture/i386/linker.ld \ +LDFLAGS += -Tarch/i386/linker.ld \ -fno-pic -fno-pie \ -Wl,-static,--no-dynamic-linker,-ztext \ -zmax-page-size=0x1000 \ @@ -87,9 +87,9 @@ else ifeq ($(OSARCH), aarch64) CFLAGS += -fno-builtin -Wstack-protector -Daa64 -fPIC -mno-outline-atomics CFLAG_STACK_PROTECTOR := -fstack-protector-all -LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC -pie \ - -Wl,-static,--no-dynamic-linker,-ztext \ - -zmax-page-size=0x1000 \ +LDFLAGS += -Tarch/aarch64/linker.ld -fPIC -pie \ + -Wl,-static,--no-dynamic-linker,-ztext \ + -zmax-page-size=0x1000 \ -Wl,-Map kernel.map endif diff --git a/Modules/ATA/ata.hpp b/Modules/ATA/ata.hpp deleted file mode 100644 index d514d5a8..00000000 --- a/Modules/ATA/ata.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_ATA_H__ -#define __FENNIX_KERNEL_ATA_H__ - -#include -#include "../../DAPI.hpp" - -namespace AdvancedTechnologyAttachment -{ - int DriverEntry(void *); - int CallbackHandler(KernelCallback *); - int InterruptCallback(CPURegisters *); -} - -#endif // !__FENNIX_KERNEL_ATA_H__ diff --git a/Modules/AdvancedMicroDevices/pcnet.hpp b/Modules/AdvancedMicroDevices/pcnet.hpp deleted file mode 100644 index 98b59afe..00000000 --- a/Modules/AdvancedMicroDevices/pcnet.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_AMD_PCNET_H__ -#define __FENNIX_KERNEL_AMD_PCNET_H__ - -#include -#include "../../DAPI.hpp" - -namespace PCNET -{ - struct BARData - { - uint8_t Type; - uint16_t IOBase; - uint64_t MemoryBase; - }; - - int DriverEntry(void *); - int CallbackHandler(KernelCallback *); - int InterruptCallback(CPURegisters *); -} - -#endif // !__FENNIX_KERNEL_AMD_PCNET_H__ diff --git a/Modules/PersonalSystem2/Keyboard.cpp b/Modules/PersonalSystem2/Keyboard.cpp deleted file mode 100644 index a55f99d2..00000000 --- a/Modules/PersonalSystem2/Keyboard.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include "keyboard.hpp" - -#include -#include -#include - -#include "../../DAPI.hpp" -#include "../drv.hpp" -#include "../../kernel.h" - -namespace PS2Keyboard -{ - KernelAPI KAPI; - - uint8_t ScanCode = 0; - bool InputReceived = false; - - int DriverEntry(void *Data) - { - if (!Data) - return INVALID_KERNEL_API; - KAPI = *(KernelAPI *)Data; - if (KAPI.Version.Major < 0 || KAPI.Version.Minor < 0 || KAPI.Version.Patch < 0) - return KERNEL_API_VERSION_NOT_SUPPORTED; - - return OK; - } - - int CallbackHandler(KernelCallback *Data) - { - switch (Data->Reason) - { - case AcknowledgeReason: - { - debug("Kernel acknowledged the driver."); - break; - } - case ConfigurationReason: - { - while (inb(0x64) & 0x1) - inb(0x60); - - outb(0x64, 0xAE); - outb(0x64, 0x20); - uint8_t ret = (inb(0x60) | 1) & ~0x10; - outb(0x64, 0x60); - outb(0x60, ret); - outb(0x60, 0xF4); - - outb(0x21, 0xFD); - outb(0xA1, 0xFF); - - trace("PS/2 keyboard configured."); - break; - } - case QueryReason: - { - Data->InputCallback.Keyboard.Key = ScanCode; - break; - } - case PollWaitReason: - { - while (!InputReceived) - TaskManager->Yield(); - InputReceived = false; - - Data->InputCallback.Keyboard.Key = ScanCode; - break; - } - case StopReason: - { - fixme("Driver stopped."); - break; - } - default: - { - warn("Unknown reason."); - break; - } - } - return OK; - } - - int InterruptCallback(CPURegisters *) - { - ScanCode = inb(0x60); - InputReceived = true; - return OK; - } -} diff --git a/Network/Checksum.cpp b/Network/Checksum.cpp deleted file mode 100644 index ab33674d..00000000 --- a/Network/Checksum.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -uint16_t CalculateChecksum(uint16_t *Data, size_t Length) -{ - uint16_t *Data16 = (uint16_t *)Data; - uint64_t Checksum = 0; - for (uint64_t i = 0; i < Length / 2; i++) - Checksum += ((Data16[i] & 0xFF00) >> 8) | ((Data16[i] & 0x00FF) << 8); - if (Length % 2) - Checksum += ((uint16_t)((char *)Data16)[Length - 1]) << 8; - while (Checksum & 0xFFFF0000) - Checksum = (Checksum & 0xFFFF) + (Checksum >> 16); - return (uint16_t)(((~Checksum & 0xFF00) >> 8) | ((~Checksum & 0x00FF) << 8)); -} diff --git a/Network/DomainNameSystem.cpp b/Network/DomainNameSystem.cpp deleted file mode 100644 index 46593bcf..00000000 --- a/Network/DomainNameSystem.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -#include "../kernel.h" - -namespace NetworkDNS -{ - DNS::DNS(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents() - { - debug("DNS interface %#lx created.", this); - this->UDPSocket = Socket; - } - - DNS::~DNS() - { - debug("DNS interface %#lx destroyed.", this); - } -} diff --git a/Network/TransmissionControlProtocol.cpp b/Network/TransmissionControlProtocol.cpp deleted file mode 100644 index 7a4b2bc7..00000000 --- a/Network/TransmissionControlProtocol.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include - -#include "../kernel.h" - -namespace NetworkTCP -{ -} diff --git a/Profiling/gprof.cpp b/Profiling/gprof.cpp deleted file mode 100644 index 53fab552..00000000 --- a/Profiling/gprof.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include - -#include "../kernel.h" - -using namespace UniversalAsynchronousReceiverTransmitter; - -static inline SafeFunction NIF void gprof_uart_wrapper(char c, void *unused) -{ - UART(COM2).Write(c); - UNUSED(unused); -} - -EXTERNC SafeFunction NIF void mcount(unsigned long frompc, unsigned long selfpc) -{ - // TODO: Implement - /* https://docs.kernel.org/trace/ftrace-design.html */ - UNUSED(frompc); - UNUSED(selfpc); -} diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp deleted file mode 100644 index 97736bef..00000000 --- a/SystemCalls/Native.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include -#include -#include -#include -#include - -#include "../syscalls.h" -#include "../kernel.h" -#include "../ipc.h" - -#if defined(a64) || defined(aa64) -static ssize_t ConvertErrno(ssize_t r) -{ - if (r >= 0) - return r; - return -errno; -} -#endif - -static int ConvertErrno(int r) -{ - if (r >= 0) - return r; - return -errno; -} - -struct SyscallData -{ - const char *Name; - void *Handler; - int RequiredID; -}; - -using InterProcessCommunication::IPC; -using InterProcessCommunication::IPCID; -using Tasking::PCB; -using Tasking::TCB; -using Tasking::TaskStatus::Ready; -using Tasking::TaskStatus::Terminated; -using namespace Memory; - -#define SysFrm SyscallsFrame - -#if defined(a64) -typedef long arch_t; -#elif defined(a32) -typedef int arch_t; -#endif - -__noreturn static void sys_exit(SysFrm *, int Code) -{ - trace("Userspace thread %s(%d) exited with code %d (%#x)", - thisThread->Name, - thisThread->ID, Code, - Code < 0 ? -Code : Code); - - thisThread->ExitCode = Code; - thisThread->Status = Terminated; - TaskManager->Yield(); - __builtin_unreachable(); -} - -static uintptr_t sys_request_pages(SysFrm *, size_t Count) -{ - MemMgr *MemMgr = thisThread->Memory; - return (uintptr_t)MemMgr->RequestPages(Count + 1, true); -} - -static int sys_free_pages(SysFrm *, uintptr_t Address, - size_t Count) -{ - MemMgr *MemMgr = thisThread->Memory; - MemMgr->FreePages((void *)Address, Count + 1); - return 0; -} - -static int sys_detach_address(SysFrm *, uintptr_t Address) -{ - MemMgr *MemMgr = thisThread->Memory; - MemMgr->DetachAddress((void *)Address); - return 0; -} - -static int sys_memory_map(SysFrm *, uintptr_t VirtualAddress, - uintptr_t PhysicalAddress, size_t Size, - int Flags) -{ - if (Flags > 7) /* (MAP_PRESENT | MAP_WRITABLE | MAP_USER) */ - return -EINVAL; - - PageTable *PageTable = thisProcess->PageTable; - { - Virtual vmm = Virtual(PageTable); - vmm.Map((void *)VirtualAddress, - (void *)PhysicalAddress, - Size, Flags); - } - - return 0; -} - -static int sys_memory_unmap(SysFrm *, uintptr_t VirtualAddress, - size_t Size) -{ - PageTable *PageTable = thisProcess->PageTable; - { - Virtual vmm = Virtual(PageTable); - vmm.Unmap((void *)VirtualAddress, - Size); - } - - return 0; -} - -static arch_t sys_kernelctl(SysFrm *, KCtl Command, - arch_t Arg1, arch_t Arg2, - arch_t Arg3, arch_t Arg4) -{ - UNUSED(Arg2); - UNUSED(Arg3); - UNUSED(Arg4); - - switch (Command) - { - case KCTL_PRINT: - { - SmartHeap sh(strlen((const char *)Arg1) + 1); - sh = Arg1; - KPrint(sh); - return 0; - } - case KCTL_GET_PAGE_SIZE: - return PAGE_SIZE; - case KCTL_IS_CRITICAL: - return thisThread->Security.IsCritical; - default: - { - warn("KernelCTL: Unknown command: %d", Command); - return -EINVAL; - } - } -} - -static int sys_file_open(SysFrm *, const char *Path, - int Flags, mode_t Mode) -{ - function("%s, %d, %d", Path, Flags, Mode); - PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_open(Path, Flags, Mode)); -} - -static int sys_file_close(SysFrm *, int FileDescriptor) -{ - function("%d", FileDescriptor); - PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_close(FileDescriptor)); -} - -static uint64_t sys_file_read(SysFrm *, int FileDescriptor, - void *Buffer, size_t Count) -{ - function("%d, %p, %d", FileDescriptor, Buffer, Count); - PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_read(FileDescriptor, Buffer, Count)); -} - -static uint64_t sys_file_write(SysFrm *, int FileDescriptor, - const void *Buffer, size_t Count) -{ - function("%d, %p, %d", FileDescriptor, Buffer, Count); - PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_write(FileDescriptor, Buffer, Count)); -} - -static off_t sys_file_seek(SysFrm *, int FileDescriptor, - off_t Offset, int Whence) -{ - function("%d, %d, %d", FileDescriptor, Offset, Whence); - PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_lseek(FileDescriptor, Offset, Whence)); -} - -static int sys_file_status(SysFrm *, int FileDescriptor, - struct stat *StatBuffer) -{ - function("%d", FileDescriptor); - PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_fstat(FileDescriptor, StatBuffer)); -} - -static int sys_ipc(SysFrm *, enum IPCCommand Command, - enum IPCType Type, int ID, int Flags, - void *Buffer, size_t Size) -{ - InterProcessCommunication::IPC *ipc = thisProcess->IPC; - return ipc->HandleSyscall(Command, Type, ID, Flags, Buffer, Size); -} - -static long sys_local_thread_state(SysFrm *, int Code, - unsigned long Address) -{ - /* TODO: return EFAULT if Address is not mapped */ - /* TODO: return EINVAL if Code is invalid */ - /* TODO: return EPERM if Address is outside of process address space */ -#if defined(a64) || defined(aa64) - switch (Code) - { - case LTS_SET_GS: - { - wrmsr(CPU::x64::MSR_GS_BASE, Address); - return 0; - } - case LTS_GET_GS: - { - return rdmsr(CPU::x64::MSR_GS_BASE); - } - case LTS_SET_FS: - { - wrmsr(CPU::x64::MSR_FS_BASE, Address); - return 0; - } - case LTS_GET_FS: - { - return rdmsr(CPU::x64::MSR_FS_BASE); - } - case LTS_SET_CPUID: - { - fixme("TLS_SET_CPUID"); - return -ENOSYS; - } - case LTS_GET_CPUID: - { - fixme("TLS_GET_CPUID"); - return -ENOSYS; - } - default: - return -EINVAL; - } -#endif - return -ENOSYS; -} - -static int sys_sleep(SysFrm *, uint64_t Milliseconds) -{ - TaskManager->Sleep(Milliseconds, true); - return 0; -} - -static int sys_fork(SysFrm *Frame) -{ -#ifdef a32 - return -ENOSYS; -#endif - PCB *Parent = thisThread->Parent; - TCB *Thread = thisThread; - - void *ProcSymTable = nullptr; - if (Parent->ELFSymbolTable) - ProcSymTable = Parent->ELFSymbolTable->GetImage(); - - PCB *NewProcess = - TaskManager->CreateProcess(Parent, - Parent->Name, - Parent->Security.ExecutionMode, - ProcSymTable); - - if (!NewProcess) - { - error("Failed to create process for fork"); - return -EAGAIN; - } - - NewProcess->IPC->Fork(Parent->IPC); - - TCB *NewThread = - TaskManager->CreateThread(NewProcess, - 0, - nullptr, - nullptr, - std::vector(), - Thread->Info.Architecture, - Thread->Info.Compatibility, - true); - - NewThread->Rename(Thread->Name); - - if (!NewThread) - { - error("Failed to create thread for fork"); - return -EAGAIN; - } - - static int RetChild = 0; - static uint64_t ReturnAddress = 0; - static uint64_t ChildStackPointer = 0; - - TaskManager->UpdateFrame(); - - if (RetChild--) - { - /* We can't just return 0; because the - CPUData->SystemCallStack is no - longer valid */ -#if defined(a64) || defined(aa64) - asmv("movq %0, %%rcx\n" - : - : "r"(ReturnAddress)); - asmv("mov %0, %%rsp\n" - : - : "r"(ChildStackPointer)); - asmv("mov %0, %%rbp\n" - : - : "r"(ChildStackPointer)); - asmv("movq $0, %rax\n"); /* Return 0 to the child */ - asmv("swapgs\n"); /* Swap GS back to the user GS */ - asmv("sti\n"); /* Enable interrupts */ - asmv("sysretq\n"); /* Return to rcx address in user mode */ -#elif defined(a32) - UNUSED(ReturnAddress); - UNUSED(ChildStackPointer); -#endif - } - RetChild = 1; - ReturnAddress = Frame->ReturnAddress; - ChildStackPointer = Frame->StackPointer; - - memcpy(&NewThread->FPU, &Thread->FPU, sizeof(CPU::x64::FXState)); - NewThread->Stack->Fork(Thread->Stack); - NewThread->Info = Thread->Info; - NewThread->Registers = Thread->Registers; - - if (Thread->Security.IsCritical) - NewThread->SetCritical(true); - -#ifdef a86 - NewThread->ShadowGSBase = Thread->ShadowGSBase; - NewThread->GSBase = Thread->GSBase; - NewThread->FSBase = Thread->FSBase; -#endif - - debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", - Thread->Name, Thread->ID, - NewThread->Name, NewThread->ID); - NewThread->Status = Ready; - return (int)NewThread->ID; -} - -static int sys_wait(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_kill(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_spawn(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_spawn_thread(SysFrm *, uint64_t InstructionPointer) -{ - TCB *thread = - TaskManager->CreateThread(thisProcess, - Tasking::IP(InstructionPointer)); - if (thread) - return (int)thread->ID; - return -EAGAIN; -} - -static int sys_get_thread_list_of_process(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_get_current_process(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_get_current_thread(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_get_current_process_id(SysFrm *) -{ - return (int)thisProcess->ID; -} - -static int sys_get_current_thread_id(SysFrm *) -{ - return (int)thisThread->ID; -} - -static int sys_get_process_by_pid(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_get_thread_by_tid(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_kill_process(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_kill_thread(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_sys_reserved_create_process(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static int sys_sys_reserved_create_thread(SysFrm *) -{ - stub; - return -ENOSYS; -} - -static SyscallData NativeSyscallsTable[sys_MaxSyscall] = { - /** - * - * Basic syscalls - * - */ - - [sys_Exit] = { - "Exit", - (void *)sys_exit, - UINT16_MAX, - }, - - /** - * - * Memory syscalls - * - */ - - [sys_RequestPages] = { - "RequestPages", - (void *)sys_request_pages, - UINT16_MAX, - }, - [sys_FreePages] = { - "FreePages", - (void *)sys_free_pages, - UINT16_MAX, - }, - [sys_DetachAddress] = { - "DetachAddress", - (void *)sys_detach_address, - 99, - }, - [sys_MemoryMap] = { - "MemoryMap", - (void *)sys_memory_map, - 99, - }, - [sys_MemoryUnmap] = { - "MemoryUnmap", - (void *)sys_memory_unmap, - 99, - }, - - /** - * - * Kernel Control syscalls - * - */ - - [sys_KernelCTL] = { - "KernelCTL", - (void *)sys_kernelctl, - 99, - }, - - /** - * - * File syscalls - * - */ - - [sys_FileOpen] = { - "FileOpen", - (void *)sys_file_open, - UINT16_MAX, - }, - [sys_FileClose] = { - "FileClose", - (void *)sys_file_close, - UINT16_MAX, - }, - [sys_FileRead] = { - "FileRead", - (void *)sys_file_read, - UINT16_MAX, - }, - [sys_FileWrite] = { - "FileWrite", - (void *)sys_file_write, - UINT16_MAX, - }, - [sys_FileSeek] = { - "FileSeek", - (void *)sys_file_seek, - UINT16_MAX, - }, - [sys_FileStatus] = { - "FileStatus", - (void *)sys_file_status, - UINT16_MAX, - }, - - /** - * - * Process syscalls - * - */ - - [sys_IPC] = { - "IPC", - (void *)sys_ipc, - UINT16_MAX, - }, - [sys_LocalThreadState] = { - "LocalThreadState", - (void *)sys_local_thread_state, - UINT16_MAX, - }, - [sys_Sleep] = { - "Sleep", - (void *)sys_sleep, - UINT16_MAX, - }, - [sys_Fork] = { - "Fork", - (void *)sys_fork, - UINT16_MAX, - }, - [sys_Wait] = { - "Wait", - (void *)sys_wait, - 0, - }, - [sys_Kill] = { - "Kill", - (void *)sys_kill, - 0, - }, - [sys_Spawn] = { - "Spawn", - (void *)sys_spawn, - 0, - }, - [sys_SpawnThread] = { - "SpawnThread", - (void *)sys_spawn_thread, - 0, - }, - [sys_GetThreadListOfProcess] = { - "GetThreadListOfProcess", - (void *)sys_get_thread_list_of_process, - 0, - }, - [sys_GetCurrentProcess] = { - "GetCurrentProcess", - (void *)sys_get_current_process, - 0, - }, - [sys_GetCurrentThread] = { - "GetCurrentThread", - (void *)sys_get_current_thread, - 0, - }, - [sys_GetCurrentProcessID] = { - "GetCurrentProcessID", - (void *)sys_get_current_process_id, - UINT16_MAX, - }, - [sys_GetCurrentThreadID] = { - "GetCurrentThreadID", - (void *)sys_get_current_thread_id, - UINT16_MAX, - }, - [sys_GetProcessByPID] = { - "GetProcessByPID", - (void *)sys_get_process_by_pid, - 0, - }, - [sys_GetThreadByTID] = { - "GetThreadByTID", - (void *)sys_get_thread_by_tid, - 0, - }, - [sys_KillProcess] = { - "KillProcess", - (void *)sys_kill_process, - 0, - }, - [sys_KillThread] = { - "KillThread", - (void *)sys_kill_thread, - 0, - }, - [sys_SysReservedCreateProcess] = { - "SysReservedCreateProcess", - (void *)sys_sys_reserved_create_process, - 0, - }, - [sys_SysReservedCreateThread] = { - "SysReservedCreateThread", - (void *)sys_sys_reserved_create_thread, - 0, - }, -}; - -uintptr_t HandleNativeSyscalls(SysFrm *Frame) -{ -#if defined(a64) - if (unlikely(Frame->rax > sys_MaxSyscall)) - { - fixme("Syscall %ld not implemented.", Frame->rax); - return -ENOSYS; - } - - SyscallData Syscall = NativeSyscallsTable[Frame->rax]; - - uintptr_t (*call)(SysFrm *, uintptr_t, ...) = - r_cst(uintptr_t(*)(SysFrm *, uintptr_t, ...), - Syscall.Handler); - - if (unlikely(!call)) - { - error("Syscall %s(%d) not implemented.", - Syscall.Name, Frame->rax); - return -ENOSYS; - } - - int euid = thisProcess->Security.Effective.UserID; - int egid = thisProcess->Security.Effective.GroupID; - int reqID = Syscall.RequiredID; - if (euid > reqID || egid > reqID) - { - warn("Process %s(%d) tried to access a system call \"%s\" with insufficient privileges.", - thisProcess->Name, thisProcess->ID, Syscall.Name); - debug("Required: %d; Effective u:%d, g:%d", reqID, euid, egid); - return -EPERM; - } - - debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )", - Frame->rax, Syscall.Name, - Frame->rdi, Frame->rsi, Frame->rdx, - Frame->r10, Frame->r8, Frame->r9); - - return call(Frame, - Frame->rdi, Frame->rsi, Frame->rdx, - Frame->r10, Frame->r8, Frame->r9); -#elif defined(a32) - if (unlikely(Frame->eax > sys_MaxSyscall)) - { - fixme("Syscall %ld not implemented.", Frame->eax); - return -ENOSYS; - } - - SyscallData Syscall = NativeSyscallsTable[Frame->eax]; - - uintptr_t (*call)(SysFrm *, uintptr_t, ...) = - r_cst(uintptr_t(*)(SysFrm *, uintptr_t, ...), - Syscall.Handler); - - if (unlikely(!call)) - { - error("Syscall %s(%d) not implemented.", - Syscall.Name, Frame->eax); - return -ENOSYS; - } - - int euid = thisProcess->Security.Effective.UserID; - int egid = thisProcess->Security.Effective.GroupID; - int reqID = Syscall.RequiredID; - if (euid > reqID || egid > reqID) - { - warn("Process %s(%d) tried to access a system call \"%s\" with insufficient privileges.", - thisProcess->Name, thisProcess->ID, Syscall.Name); - debug("Required: %d; Effective u:%d, g:%d", reqID, euid, egid); - return -EPERM; - } - - debug("[%d:\"%s\"]->( %#x %#x %#x %#x %#x %#x )", - Frame->eax, Syscall.Name, - Frame->ebx, Frame->ecx, Frame->edx, - Frame->esi, Frame->edi, Frame->ebp); - - return call(Frame, - Frame->ebx, Frame->ecx, Frame->edx, - Frame->esi, Frame->edi, Frame->ebp); -#elif defined(aa64) - return -ENOSYS; -#endif -} diff --git a/SystemCalls/Syscalls.cpp b/SystemCalls/Syscalls.cpp deleted file mode 100644 index e1ba8c40..00000000 --- a/SystemCalls/Syscalls.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include - -#include - -#include "../kernel.h" - -class AutoSwitchPageTable -{ -private: - uintptr_t Original; - -public: - AutoSwitchPageTable() - { -#if defined(a86) - asmv("mov %%cr3, %0" - : "=r"(Original)); - - asmv("mov %0, %%cr3" - : - : "r"(KernelPageTable)); -#endif - } - - ~AutoSwitchPageTable() - { -#if defined(a86) - asmv("mov %0, %%cr3" - : - : "r"(Original)); -#endif - } -}; - -extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame) -{ - /* Automatically switch to kernel page table - and switch back when this function returns. */ - AutoSwitchPageTable PageSwitcher; - - uint64_t TempTimeCalc = TimeManager->GetCounter(); - Tasking::TaskInfo *Ptinfo = &thisProcess->Info; - Tasking::TaskInfo *Ttinfo = &thisThread->Info; - - switch (Ttinfo->Compatibility) - { - case Tasking::TaskCompatibility::Native: - { - uintptr_t ret = 0; - if (Config.UseLinuxSyscalls) - ret = HandleLinuxSyscalls(Frame); - else - ret = HandleNativeSyscalls(Frame); - Ptinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc; - Ttinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc; - return ret; - } - case Tasking::TaskCompatibility::Linux: - { - uintptr_t ret = HandleLinuxSyscalls(Frame); - Ptinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc; - Ttinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc; - return ret; - } - case Tasking::TaskCompatibility::Windows: - { - error("Windows compatibility not implemented yet."); - break; - } - default: - { - error("Unknown compatibility mode! Killing thread..."); - TaskManager->KillThread(thisThread, Tasking::KILL_SYSCALL); - break; - } - } - assert(false); /* Should never reach here. */ - return 0; -} diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..9f714b48 --- /dev/null +++ b/TODO.md @@ -0,0 +1,28 @@ +- [x] Optimize SMP. +- [ ] Support IPv6. +- [ ] Endianess of the network stack (currently: [HOST](LSB)<=>[NETWORK](MSB)). Not sure if this is a standard or not. +- [ ] Support 32-bit applications (ELF, PE, etc). +- [ ] Do not map the entire memory. Map only the needed memory address at allocation time. +- [ ] Implementation of logging (beside serial) with log rotation. +- [x] Implement a better task manager. (replace struct P/TCB with classes) +- [ ] Rewrite virtual file system. (it's very bad, I don't know how I wrote it this bad) +- [ ] Colors in crash screen are not following the kernel color scheme. +- [x] Find a way to add intrinsics. +- [ ] Rework PSF1 font loader. +- [x] The cleanup should be done by a thread (tasking). This is done to avoid a deadlock. +- [ ] Implement a better Display::SetBrightness() function. +- [ ] Fix memcpy, memset and memcmp functions (they are not working properly with SIMD). +- [x] Fully support i386. +- [ ] Support Aarch64. +- [ ] SMP trampoline shouldn't be hardcoded at 0x2000. +- [ ] Rework the stack guard. +- [x] Mutex implementation. +- [ ] Update SMBIOS functions to support newer versions and actually use it. +- [ ] COW (Copy On Write) for the virtual memory. (https://en.wikipedia.org/wiki/Copy-on-write) +- [ ] Implement lazy allocation. (page faults) +- [ ] Bootstrap should have a separate bss section + PHDR. +- [ ] Reimplement the driver conflict detection. +- [ ] Elf loader shouldn't create a full copy of the elf binary. Copy only the needed sections. +- [ ] Use NX-bit. +- [ ] Fix std::string +- [ ] Rewrite PS/2 drivers. diff --git a/Tests/Marco.cpp b/Tests/Marco.cpp deleted file mode 100644 index 089e9fa9..00000000 --- a/Tests/Marco.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifdef DEBUG - -#include -#include -#include -#include - -#include -#include "../syscalls.h" - -void TestSeekMacros() /* static assert, no constructor needed */ -{ - static_assert(SYSCALL_SEEK_SET == SEEK_SET); - static_assert(SYSCALL_SEEK_CUR == SEEK_CUR); - static_assert(SYSCALL_SEEK_END == SEEK_END); -} - -__constructor void TestMacros() -{ - { - int a = TO_PAGES(4096); - int b = FROM_PAGES(1); - - debug("a: 4096 -> %d", a); - debug("b: a -> %d", b); - - if (a != 1) - { - error("t1: TO_PAGES is not equal to 1"); - inf_loop; - } - - if (b != 4096) - { - error("t1: FROM_PAGES is not equal to 4096"); - inf_loop; - } - } - - { - int a = TO_PAGES(4097); - int b = FROM_PAGES(2); - - debug("a: 4097 -> %d", a); - debug("b: a -> %d", b); - - if (a != 2) - { - error("t2: TO_PAGES is not equal to 2"); - inf_loop; - } - - if (b != 8192) - { - error("t2: FROM_PAGES is not equal to 8192"); - inf_loop; - } - } - - { - int a = 10; - assert(a == 10); - - const char *str = "Hello"; - assert(str != nullptr && str[0] == 'H'); - - bool flag = false; - assert(!flag); - } - - debug("-------------------------"); - - { - uint64_t bytes = PAGE_SIZE; - uint64_t pgs = 1; - - for (int i = 0; i < 128; i++) - { - uint64_t cnv_to_pgs = TO_PAGES(bytes); - uint64_t cnv_from_pgs = FROM_PAGES(pgs); - - if (cnv_to_pgs != pgs) - { - error("TO_PAGES is not equal to %d (pages: %d)", pgs, cnv_to_pgs); - inf_loop; - } - - if (cnv_from_pgs != bytes) - { - error("FROM_PAGES is not equal to %d (bytes: %d)", bytes, cnv_from_pgs); - inf_loop; - } - - bytes += PAGE_SIZE; - pgs++; - } - } - - { - debug("Testing ROUND_UP and ROUND_DOWN"); - int x = 0x101; - int y = 0x100; - int result; - - result = ROUND_UP(x, y); - if (result != 0x200) - { - error("ERROR: ROUND_UP failed: %d != 0x200", result); - inf_loop; - } - - result = ROUND_DOWN(x, y); - if (result != 0x100) - { - error("ERROR: ROUND_DOWN failed: %d != 0x100", result); - inf_loop; - } - } -} - -#endif // DEBUG diff --git a/Tests/t.h b/Tests/t.h deleted file mode 100644 index 9525b5cf..00000000 --- a/Tests/t.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_non_constructor_tests_H__ -#define __FENNIX_KERNEL_non_constructor_tests_H__ -#ifdef DEBUG - -#include - -void TestString(); -void Test_std(); -void TestMemoryAllocation(); - -#endif // DEBUG -#endif // !__FENNIX_KERNEL_non_constructor_tests_H__ diff --git a/Architecture/aarch64/Bootstrap/boot.S b/arch/aarch64/bootstrap/boot.S similarity index 100% rename from Architecture/aarch64/Bootstrap/boot.S rename to arch/aarch64/bootstrap/boot.S diff --git a/arch/aarch64/cpu/smp.cpp b/arch/aarch64/cpu/smp.cpp new file mode 100644 index 00000000..7f6454dc --- /dev/null +++ b/arch/aarch64/cpu/smp.cpp @@ -0,0 +1,59 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include + +#include "../../../kernel.h" + +volatile bool CPUEnabled = false; + +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +static __aligned(0x1000) CPUData CPUs[MAX_CPU] = {0}; + +CPUData *GetCPU(uint64_t id) { return &CPUs[id]; } + +CPUData *GetCurrentCPU() +{ + uint64_t ret = 0; + + if (!CPUs[ret].IsActive) + { + error("CPU %d is not active!", ret); + return &CPUs[0]; + } + + if (CPUs[ret].Checksum != CPU_DATA_CHECKSUM) + { + error("CPU %d data is corrupted!", ret); + return &CPUs[0]; + } + return &CPUs[ret]; +} + +namespace SMP +{ + int CPUCores = 0; + + void Initialize(void *madt) + { + fixme("SMP::Initialize() is not implemented!"); + } +} diff --git a/arch/aarch64/entry.cpp b/arch/aarch64/entry.cpp new file mode 100644 index 00000000..7b0fb756 --- /dev/null +++ b/arch/aarch64/entry.cpp @@ -0,0 +1,27 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +EXTERNC void arm64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3) +{ + trace("Hello, World!"); + CPU::Halt(true); +} diff --git a/arch/aarch64/linker.ld b/arch/aarch64/linker.ld new file mode 100644 index 00000000..d1c471ef --- /dev/null +++ b/arch/aarch64/linker.ld @@ -0,0 +1,90 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +ENTRY(_start) + +SECTIONS +{ + _bootstrap_start = .; + .text.boot : + { + *(.text.boot) + . += CONSTANT(MAXPAGESIZE); + _bss_start = .; + *(.text.bss) + _bss_end = .; + } + _bootstrap_end = .; + + _kernel_start = .; + _kernel_text_start = .; + .text : + { + KEEP(*(.text.boot)) + *(.text .text.*) + } + . = ALIGN(4096); + _kernel_text_end = .; + + _kernel_data_start = .; + .data : + { + *(.data .data.*) + } + . = ALIGN(4096); + _kernel_data_end = .; + + _kernel_rodata_start = .; + .rodata : + { + *(.rodata .rodata.*) + } + . = ALIGN(4096); + + .init_array : + { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(.init_array .ctors)) + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + PROVIDE_HIDDEN (__init_array_end = .); + } + + .fini_array : + { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP(*(.fini_array .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + _kernel_rodata_end = .; + + _kernel_bss_start = .; + .bss : + { + *(.bss .bss.*) + } + . = ALIGN(4096); + _kernel_bss_end = .; + _kernel_end = .; + _bss_size = _kernel_end - _kernel_rodata_end; + + /DISCARD/ : + { + *(.comment*) + *(.note*) + } +} diff --git a/arch/aarch64/memory/vmm.cpp b/arch/aarch64/memory/vmm.cpp new file mode 100644 index 00000000..bfd3461f --- /dev/null +++ b/arch/aarch64/memory/vmm.cpp @@ -0,0 +1,40 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +namespace Memory +{ + bool Virtual::Check(void *VirtualAddress, PTFlag Flag, MapType Type) + { + } + + void *Virtual::GetPhysical(void *VirtualAddress) + { + } + + void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type) + { + } + + void Virtual::Unmap(void *VirtualAddress, MapType Type) + { + } +} diff --git a/arch/aarch64/syscalls.cpp b/arch/aarch64/syscalls.cpp new file mode 100644 index 00000000..4530a6b8 --- /dev/null +++ b/arch/aarch64/syscalls.cpp @@ -0,0 +1,31 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include + +extern "C" __naked __used __no_stack_protector void SystemCallHandlerStub() +{ + +} + +extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs); + +void InitializeSystemCalls() +{ +} diff --git a/arch/amd64/bootstrap/_start.s b/arch/amd64/bootstrap/_start.s new file mode 100644 index 00000000..692d60be --- /dev/null +++ b/arch/amd64/bootstrap/_start.s @@ -0,0 +1,38 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.code32 +.extern Multiboot_start + +.section .bootstrap.text, "a" + +.global _start +_start: + /* Check for multiboot */ + cmp $0x2BADB002, %eax + je .Multiboot + + /* Unkown bootloader */ + .Hang: + cli + hlt + jmp .Hang + + /* Multiboot */ + .Multiboot: + call Multiboot_start + jmp .Hang diff --git a/Architecture/amd64/Bootstrap/Limine/Limine.c b/arch/amd64/bootstrap/limine/limine.c similarity index 93% rename from Architecture/amd64/Bootstrap/Limine/Limine.c rename to arch/amd64/bootstrap/limine/limine.c index d90fc649..3cf7e641 100644 --- a/Architecture/amd64/Bootstrap/Limine/Limine.c +++ b/arch/amd64/bootstrap/limine/limine.c @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/amd64/Bootstrap/Multiboot/Helper/Detect.s b/arch/amd64/bootstrap/multiboot/Helper/detect.s similarity index 53% rename from Architecture/amd64/Bootstrap/Multiboot/Helper/Detect.s rename to arch/amd64/bootstrap/multiboot/Helper/detect.s index 2895b2e2..258e17eb 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Helper/Detect.s +++ b/arch/amd64/bootstrap/multiboot/Helper/detect.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .intel_syntax noprefix diff --git a/arch/amd64/bootstrap/multiboot/Helper/gdt32.s b/arch/amd64/bootstrap/multiboot/Helper/gdt32.s new file mode 100644 index 00000000..b4e8afc5 --- /dev/null +++ b/arch/amd64/bootstrap/multiboot/Helper/gdt32.s @@ -0,0 +1,64 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.code32 +.section .bootstrap.text, "a" + +.align 32 +.global gdtr +gdtr: + .word GDT32_END - GDT32 - 1 + .long GDT32 + +.align 32 +GDT32: + .quad 0x0 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF9A + .byte 0x00 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF92 + .byte 0x00 + + .word 0x0100 + .word 0x1000 + .byte 0x00 + .word 0x4092 + .byte 0x00 +GDT32_END: + nop + +.global LoadGDT32 +LoadGDT32: + lgdt [gdtr] + ljmp $0x8, $ActivateGDT + +ActivateGDT: + mov $0x10, %cx + mov %cx, %ss + mov %cx, %ds + mov %cx, %es + mov %cx, %fs + mov $0x18, %cx + mov %cx, %gs + ret diff --git a/arch/amd64/bootstrap/multiboot/Helper/gdt64.s b/arch/amd64/bootstrap/multiboot/Helper/gdt64.s new file mode 100644 index 00000000..309d2191 --- /dev/null +++ b/arch/amd64/bootstrap/multiboot/Helper/gdt64.s @@ -0,0 +1,62 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.code64 +.section .bootstrap.data, "a" + +/* Access bits */ +A = 0x1 +RW = 0x2 +DC = 0x4 +E = 0x8 +S = 0x10 +DPL0 = 0x0 /* 0 << 5 ???? */ +DPL1 = 0x20 +P = 0x80 + +/* Flags bits */ +LONG_MODE = 0x20 +SZ_32 = 0x40 +GRAN_4K = 0x80 + +.global GDT64.Null +.global GDT64.Code +.global GDT64.Data +.global GDT64.Tss +.global GDT64.Ptr + +GDT64: +GDT64.Null = . - GDT64 + .quad 0 +GDT64.Code = . - GDT64 + .long 0xFFFF + .byte 0 + .byte P | S | E | RW + .byte GRAN_4K | LONG_MODE | 0xF + .byte 0 +GDT64.Data = . - GDT64 + .long 0xFFFF + .byte 0 + .byte P | S | RW + .byte GRAN_4K | SZ_32 | 0xF + .byte 0 +GDT64.Tss = . - GDT64 + .long 0x00000068 + .long 0x00CF8900 +GDT64.Ptr: + .word . - GDT64 - 1 + .quad GDT64 diff --git a/Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot64bitMap.cpp b/arch/amd64/bootstrap/multiboot/Paging/mb_64bit_map.cpp similarity index 91% rename from Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot64bitMap.cpp rename to arch/amd64/bootstrap/multiboot/Paging/mb_64bit_map.cpp index 337a8310..6fc9de83 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot64bitMap.cpp +++ b/arch/amd64/bootstrap/multiboot/Paging/mb_64bit_map.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s b/arch/amd64/bootstrap/multiboot/Paging/mb_pt.s similarity index 71% rename from Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s rename to arch/amd64/bootstrap/multiboot/Paging/mb_pt.s index b2d8643f..d0c05aa5 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s +++ b/arch/amd64/bootstrap/multiboot/Paging/mb_pt.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ PAGE_TABLE_SIZE = 0x4 diff --git a/arch/amd64/bootstrap/multiboot/headers/header1.s b/arch/amd64/bootstrap/multiboot/headers/header1.s new file mode 100644 index 00000000..a91af89c --- /dev/null +++ b/arch/amd64/bootstrap/multiboot/headers/header1.s @@ -0,0 +1,38 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.code32 +.extern Multiboot_start + +.section .multiboot, "a" +.align 4 + +MULTIBOOT_HEADER: + .long 0x1BADB002 + .long 0x1 | 0x2 | 0x4 + .long -(0x1BADB002 + (0x1 | 0x2 | 0x4)) + /* KLUDGE */ + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + /* VIDEO MODE */ + .long 0 + .long 0 + .long 0 + .long 0 diff --git a/Architecture/amd64/Bootstrap/Multiboot/Headers/Header2.s b/arch/amd64/bootstrap/multiboot/headers/header2.s similarity index 73% rename from Architecture/amd64/Bootstrap/Multiboot/Headers/Header2.s rename to arch/amd64/bootstrap/multiboot/headers/header2.s index 5217f105..f81e8e34 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Headers/Header2.s +++ b/arch/amd64/bootstrap/multiboot/headers/header2.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .code32 diff --git a/Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp b/arch/amd64/bootstrap/multiboot/mb1_parse.cpp similarity index 91% rename from Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp rename to arch/amd64/bootstrap/multiboot/mb1_parse.cpp index 4733dd08..fd6caf17 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp +++ b/arch/amd64/bootstrap/multiboot/mb1_parse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp b/arch/amd64/bootstrap/multiboot/mb2_parse.cpp similarity index 93% rename from Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp rename to arch/amd64/bootstrap/multiboot/mb2_parse.cpp index 83f972c3..e85e20ad 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp +++ b/arch/amd64/bootstrap/multiboot/mb2_parse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp b/arch/amd64/bootstrap/multiboot/multiboot.cpp similarity index 57% rename from Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp rename to arch/amd64/bootstrap/multiboot/multiboot.cpp index fc670582..5d1d1bb5 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp +++ b/arch/amd64/bootstrap/multiboot/multiboot.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/amd64/Bootstrap/Multiboot/Start.s b/arch/amd64/bootstrap/multiboot/start.s similarity index 69% rename from Architecture/amd64/Bootstrap/Multiboot/Start.s rename to arch/amd64/bootstrap/multiboot/start.s index 2c2d3ade..04ed992c 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Start.s +++ b/arch/amd64/bootstrap/multiboot/start.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .code32 diff --git a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp b/arch/amd64/cpu/apic.cpp similarity index 93% rename from Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp rename to arch/amd64/cpu/apic.cpp index 9b1b5eb9..c42299eb 100644 --- a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp +++ b/arch/amd64/cpu/apic.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "apic.hpp" @@ -412,7 +412,7 @@ namespace APIC if (this->lapic->x2APIC) { - wrmsr(MSR_X2APIC_DIV_CONF, Divider); + // wrmsr(MSR_X2APIC_DIV_CONF, Divider); <- gpf on real hardware wrmsr(MSR_X2APIC_INIT_COUNT, uint32_t(Ticks * Miliseconds)); wrmsr(MSR_X2APIC_LVT_TIMER, uint32_t(timer.raw)); } diff --git a/Architecture/amd64/cpu/apic.hpp b/arch/amd64/cpu/apic.hpp similarity index 91% rename from Architecture/amd64/cpu/apic.hpp rename to arch/amd64/cpu/apic.hpp index 34aae7f4..aaf2ca50 100644 --- a/Architecture/amd64/cpu/apic.hpp +++ b/arch/amd64/cpu/apic.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_APIC_H__ diff --git a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp b/arch/amd64/cpu/gdt.cpp similarity index 88% rename from Architecture/amd64/cpu/GlobalDescriptorTable.cpp rename to arch/amd64/cpu/gdt.cpp index 45424725..2d0ff142 100644 --- a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp +++ b/arch/amd64/cpu/gdt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "gdt.hpp" diff --git a/Architecture/amd64/cpu/gdt.hpp b/arch/amd64/cpu/gdt.hpp similarity index 68% rename from Architecture/amd64/cpu/gdt.hpp rename to arch/amd64/cpu/gdt.hpp index e7246139..2b0263d7 100644 --- a/Architecture/amd64/cpu/gdt.hpp +++ b/arch/amd64/cpu/gdt.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_GDT_H__ diff --git a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp b/arch/amd64/cpu/idt.cpp similarity index 98% rename from Architecture/amd64/cpu/InterruptDescriptorTable.cpp rename to arch/amd64/cpu/idt.cpp index afc6d3ae..b87b78a3 100644 --- a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp +++ b/arch/amd64/cpu/idt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "idt.hpp" diff --git a/arch/amd64/cpu/idt.hpp b/arch/amd64/cpu/idt.hpp new file mode 100644 index 00000000..5115f168 --- /dev/null +++ b/arch/amd64/cpu/idt.hpp @@ -0,0 +1,51 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_IDT_H__ +#define __FENNIX_KERNEL_IDT_H__ + +#include +#include + +namespace InterruptDescriptorTable +{ + + union IDTGateDescriptor + { + InterruptGate Interrupt; + TrapGate Trap; + CallGate Call; + }; + + struct IDTRegister + { + uint16_t Limit; + IDTGateDescriptor *BaseAddress; + } __packed; + + void SetEntry(uint8_t Index, + void (*Base)(), + InterruptStackTableType InterruptStackTable, + GateType Gate, + PrivilegeLevelType Ring, + bool Present, + uint16_t SegmentSelector); + + void Init(int Core); +} + +#endif // !__FENNIX_KERNEL_IDT_H__ diff --git a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp b/arch/amd64/cpu/smp.cpp similarity index 87% rename from Architecture/amd64/cpu/SymmetricMultiprocessing.cpp rename to arch/amd64/cpu/smp.cpp index 89ecdd05..600072c8 100644 --- a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp +++ b/arch/amd64/cpu/smp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/amd64/cpu/SMPTrampoline.s b/arch/amd64/cpu/smp_trampoline.s similarity index 80% rename from Architecture/amd64/cpu/SMPTrampoline.s rename to arch/amd64/cpu/smp_trampoline.s index fb427729..99d02841 100644 --- a/Architecture/amd64/cpu/SMPTrampoline.s +++ b/arch/amd64/cpu/smp_trampoline.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ /* This has to be the same as enum SMPTrampolineAddress. */ diff --git a/arch/amd64/linker.ld b/arch/amd64/linker.ld new file mode 100644 index 00000000..14cdd2cf --- /dev/null +++ b/arch/amd64/linker.ld @@ -0,0 +1,104 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +OUTPUT_FORMAT(elf64-x86-64) +OUTPUT_ARCH(i386:x86-64) + +ENTRY(_start) + +PF_R = 0x4; +PF_W = 0x2; +PF_X = 0x1; + +PHDRS +{ + bootstrap PT_LOAD FLAGS( PF_R | PF_W /*| PF_X*/ ); + text PT_LOAD FLAGS( PF_R | PF_X ); + data PT_LOAD FLAGS( PF_R | PF_W ); + rodata PT_LOAD FLAGS( PF_R ); + bss PT_LOAD FLAGS( PF_R | PF_W ); +} + +KERNEL_VMA = 0xFFFFFFFF80000000; + +SECTIONS +{ + . = 0x100000; + _bootstrap_start = .; + .bootstrap ALIGN(CONSTANT(MAXPAGESIZE)) : + { + *(.multiboot) + *(.multiboot2) + *(.bootstrap .bootstrap.*) + } :bootstrap + _bootstrap_end = ALIGN(CONSTANT(MAXPAGESIZE)); + + . += KERNEL_VMA; + + _kernel_start = ALIGN(CONSTANT(MAXPAGESIZE)); + _kernel_text_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .text ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.text) - KERNEL_VMA) + { + *(.text .text.*) + } :text + _kernel_text_end = ALIGN(CONSTANT(MAXPAGESIZE)); + + _kernel_data_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .data ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.data) - KERNEL_VMA) + { + *(.data .data.*) + } :data + _kernel_data_end = ALIGN(CONSTANT(MAXPAGESIZE)); + + _kernel_rodata_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .rodata ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.rodata) - KERNEL_VMA) + { + *(.rodata .rodata.*) + } :rodata + + .init_array ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.init_array) - KERNEL_VMA) + { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(.init_array .ctors)) + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + PROVIDE_HIDDEN (__init_array_end = .); + } :rodata + + .fini_array ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.fini_array) - KERNEL_VMA) + { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP(*(.fini_array .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } :rodata + _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); + + _kernel_bss_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .bss ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.bss) - KERNEL_VMA) + { + *(COMMON) + *(.bss .bss.*) + } :bss + _kernel_bss_end = ALIGN(CONSTANT(MAXPAGESIZE)); + _kernel_end = ALIGN(CONSTANT(MAXPAGESIZE)); + + /DISCARD/ : + { + *(.comment*) + *(.note*) + } +} diff --git a/Architecture/amd64/MultipleAPICDescriptionTable.cpp b/arch/amd64/madt.cpp similarity index 77% rename from Architecture/amd64/MultipleAPICDescriptionTable.cpp rename to arch/amd64/madt.cpp index 5513b75d..03326a33 100644 --- a/Architecture/amd64/MultipleAPICDescriptionTable.cpp +++ b/arch/amd64/madt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "acpi.hpp" diff --git a/Architecture/amd64/Memory/VirtualMemoryManager.cpp b/arch/amd64/memory/vmm.cpp similarity index 91% rename from Architecture/amd64/Memory/VirtualMemoryManager.cpp rename to arch/amd64/memory/vmm.cpp index fb00ab76..a7ab2042 100644 --- a/Architecture/amd64/Memory/VirtualMemoryManager.cpp +++ b/arch/amd64/memory/vmm.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -323,20 +323,7 @@ namespace Memory PTE->Present = true; PTE->raw |= Flags; PTE->SetAddress((uintptr_t)PhysicalAddress >> 12); - -#if defined(a64) - CPU::x64::invlpg(VirtualAddress); -#elif defined(a32) CPU::x32::invlpg(VirtualAddress); -#elif defined(aa64) - asmv("dsb sy"); - asmv("tlbi vae1is, %0" - : - : "r"(VirtualAddress) - : "memory"); - asmv("dsb sy"); - asmv("isb"); -#endif #ifdef DEBUG /* https://stackoverflow.com/a/3208376/9352057 */ @@ -411,19 +398,6 @@ namespace Memory PTE.Present = false; PTEPtr->Entries[Index.PTEIndex] = PTE; - -#if defined(a64) - CPU::x64::invlpg(VirtualAddress); -#elif defined(a32) CPU::x32::invlpg(VirtualAddress); -#elif defined(aa64) - asmv("dsb sy"); - asmv("tlbi vae1is, %0" - : - : "r"(VirtualAddress) - : "memory"); - asmv("dsb sy"); - asmv("isb"); -#endif } } diff --git a/Architecture/amd64/SystemCalls.cpp b/arch/amd64/syscalls.cpp similarity index 76% rename from Architecture/amd64/SystemCalls.cpp rename to arch/amd64/syscalls.cpp index a9848868..4e750521 100644 --- a/Architecture/amd64/SystemCalls.cpp +++ b/arch/amd64/syscalls.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -24,7 +24,7 @@ // https://supercip971.github.io/02-wingos-syscalls.html using namespace CPU::x64; -// "Core/SystemCalls.cpp" +// "core/SystemCalls.cpp" extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs); extern "C" void SystemCallHandlerStub(); diff --git a/Architecture/i386/ArithmeticOperations.c b/arch/i386/arithmetic_operations.c similarity index 100% rename from Architecture/i386/ArithmeticOperations.c rename to arch/i386/arithmetic_operations.c diff --git a/Architecture/i386/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s b/arch/i386/bootstrap/Multiboot/Paging/mb_pt.s similarity index 51% rename from Architecture/i386/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s rename to arch/i386/bootstrap/Multiboot/Paging/mb_pt.s index 389b42c4..75fc017d 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s +++ b/arch/i386/bootstrap/Multiboot/Paging/mb_pt.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .code32 diff --git a/arch/i386/bootstrap/Multiboot/_start.s b/arch/i386/bootstrap/Multiboot/_start.s new file mode 100644 index 00000000..692d60be --- /dev/null +++ b/arch/i386/bootstrap/Multiboot/_start.s @@ -0,0 +1,38 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.code32 +.extern Multiboot_start + +.section .bootstrap.text, "a" + +.global _start +_start: + /* Check for multiboot */ + cmp $0x2BADB002, %eax + je .Multiboot + + /* Unkown bootloader */ + .Hang: + cli + hlt + jmp .Hang + + /* Multiboot */ + .Multiboot: + call Multiboot_start + jmp .Hang diff --git a/arch/i386/bootstrap/Multiboot/headers/header1.s b/arch/i386/bootstrap/Multiboot/headers/header1.s new file mode 100644 index 00000000..bd3cc785 --- /dev/null +++ b/arch/i386/bootstrap/Multiboot/headers/header1.s @@ -0,0 +1,27 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 +.section .multiboot, "a" +.align 4 + +MULTIBOOT_HEADER: + .long 0x1BADB002 + .long 1 << 0 | 1 << 1 + .long -(0x1BADB002 + (1 << 0 | 1 << 1)) diff --git a/Architecture/i386/Bootstrap/Multiboot/Headers/Header2.s b/arch/i386/bootstrap/Multiboot/headers/header2.s similarity index 74% rename from Architecture/i386/Bootstrap/Multiboot/Headers/Header2.s rename to arch/i386/bootstrap/Multiboot/headers/header2.s index 41c51686..a50e6224 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Headers/Header2.s +++ b/arch/i386/bootstrap/Multiboot/headers/header2.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .intel_syntax noprefix diff --git a/Architecture/i386/Bootstrap/Multiboot/Helper/Detect.s b/arch/i386/bootstrap/Multiboot/helper/detect.s similarity index 52% rename from Architecture/i386/Bootstrap/Multiboot/Helper/Detect.s rename to arch/i386/bootstrap/Multiboot/helper/detect.s index 44f6415a..5521c8c8 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Helper/Detect.s +++ b/arch/i386/bootstrap/Multiboot/helper/detect.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .intel_syntax noprefix diff --git a/arch/i386/bootstrap/Multiboot/helper/gdt32.s b/arch/i386/bootstrap/Multiboot/helper/gdt32.s new file mode 100644 index 00000000..b4e8afc5 --- /dev/null +++ b/arch/i386/bootstrap/Multiboot/helper/gdt32.s @@ -0,0 +1,64 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.code32 +.section .bootstrap.text, "a" + +.align 32 +.global gdtr +gdtr: + .word GDT32_END - GDT32 - 1 + .long GDT32 + +.align 32 +GDT32: + .quad 0x0 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF9A + .byte 0x00 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF92 + .byte 0x00 + + .word 0x0100 + .word 0x1000 + .byte 0x00 + .word 0x4092 + .byte 0x00 +GDT32_END: + nop + +.global LoadGDT32 +LoadGDT32: + lgdt [gdtr] + ljmp $0x8, $ActivateGDT + +ActivateGDT: + mov $0x10, %cx + mov %cx, %ss + mov %cx, %ds + mov %cx, %es + mov %cx, %fs + mov $0x18, %cx + mov %cx, %gs + ret diff --git a/Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp b/arch/i386/bootstrap/Multiboot/mb1_parse.cpp similarity index 91% rename from Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp rename to arch/i386/bootstrap/Multiboot/mb1_parse.cpp index 02e8ded9..b274412e 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp +++ b/arch/i386/bootstrap/Multiboot/mb1_parse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/i386/Bootstrap/Multiboot/Multiboot2Parse.cpp b/arch/i386/bootstrap/Multiboot/mb2_parse.cpp similarity index 93% rename from Architecture/i386/Bootstrap/Multiboot/Multiboot2Parse.cpp rename to arch/i386/bootstrap/Multiboot/mb2_parse.cpp index 1ae8ab8a..b8586602 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Multiboot2Parse.cpp +++ b/arch/i386/bootstrap/Multiboot/mb2_parse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp b/arch/i386/bootstrap/Multiboot/multiboot.cpp similarity index 57% rename from Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp rename to arch/i386/bootstrap/Multiboot/multiboot.cpp index fc670582..5d1d1bb5 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp +++ b/arch/i386/bootstrap/Multiboot/multiboot.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/i386/Bootstrap/Multiboot/Start.s b/arch/i386/bootstrap/Multiboot/start.s similarity index 56% rename from Architecture/i386/Bootstrap/Multiboot/Start.s rename to arch/i386/bootstrap/Multiboot/start.s index a21aae43..3df5bf4f 100644 --- a/Architecture/i386/Bootstrap/Multiboot/Start.s +++ b/arch/i386/bootstrap/Multiboot/start.s @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ .code32 diff --git a/Architecture/i386/cpu/AdvancedProgrammableInterruptController.cpp b/arch/i386/cpu/apic.cpp similarity index 94% rename from Architecture/i386/cpu/AdvancedProgrammableInterruptController.cpp rename to arch/i386/cpu/apic.cpp index a39b9e71..dd17cfa9 100644 --- a/Architecture/i386/cpu/AdvancedProgrammableInterruptController.cpp +++ b/arch/i386/cpu/apic.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "apic.hpp" diff --git a/Architecture/i386/cpu/apic.hpp b/arch/i386/cpu/apic.hpp similarity index 91% rename from Architecture/i386/cpu/apic.hpp rename to arch/i386/cpu/apic.hpp index a3001fdf..6f969d94 100644 --- a/Architecture/i386/cpu/apic.hpp +++ b/arch/i386/cpu/apic.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_APIC_H__ diff --git a/Architecture/i386/cpu/GlobalDescriptorTable.cpp b/arch/i386/cpu/gdt.cpp similarity index 90% rename from Architecture/i386/cpu/GlobalDescriptorTable.cpp rename to arch/i386/cpu/gdt.cpp index dd4167e4..a81cb5fe 100644 --- a/Architecture/i386/cpu/GlobalDescriptorTable.cpp +++ b/arch/i386/cpu/gdt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "gdt.hpp" diff --git a/Architecture/i386/cpu/gdt.hpp b/arch/i386/cpu/gdt.hpp similarity index 90% rename from Architecture/i386/cpu/gdt.hpp rename to arch/i386/cpu/gdt.hpp index 43ed2272..2f5015e9 100644 --- a/Architecture/i386/cpu/gdt.hpp +++ b/arch/i386/cpu/gdt.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_GDT_H__ diff --git a/Architecture/i386/cpu/InterruptDescriptorTable.cpp b/arch/i386/cpu/idt.cpp similarity index 98% rename from Architecture/i386/cpu/InterruptDescriptorTable.cpp rename to arch/i386/cpu/idt.cpp index e5b6d879..ad08cb38 100644 --- a/Architecture/i386/cpu/InterruptDescriptorTable.cpp +++ b/arch/i386/cpu/idt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "idt.hpp" diff --git a/Architecture/i386/cpu/idt.hpp b/arch/i386/cpu/idt.hpp similarity index 79% rename from Architecture/i386/cpu/idt.hpp rename to arch/i386/cpu/idt.hpp index 9e2a1490..aed75208 100644 --- a/Architecture/i386/cpu/idt.hpp +++ b/arch/i386/cpu/idt.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_IDT_H__ diff --git a/Architecture/i386/cpu/SymmetricMultiprocessing.cpp b/arch/i386/cpu/smp.cpp similarity index 71% rename from Architecture/i386/cpu/SymmetricMultiprocessing.cpp rename to arch/i386/cpu/smp.cpp index 50055e0f..78c2ea7f 100644 --- a/Architecture/i386/cpu/SymmetricMultiprocessing.cpp +++ b/arch/i386/cpu/smp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Architecture/i386/Interrupts/8259PIC.cpp b/arch/i386/interrupts/8259PIC.cpp similarity index 80% rename from Architecture/i386/Interrupts/8259PIC.cpp rename to arch/i386/interrupts/8259PIC.cpp index b2a5991f..ab2f5409 100644 --- a/Architecture/i386/Interrupts/8259PIC.cpp +++ b/arch/i386/interrupts/8259PIC.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "pic.hpp" diff --git a/Architecture/i386/Interrupts/pic.hpp b/arch/i386/interrupts/pic.hpp similarity index 59% rename from Architecture/i386/Interrupts/pic.hpp rename to arch/i386/interrupts/pic.hpp index fb0e5f1a..f0d6013a 100644 --- a/Architecture/i386/Interrupts/pic.hpp +++ b/arch/i386/interrupts/pic.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_8259PIC_H__ diff --git a/Architecture/i386/linker.ld b/arch/i386/linker.ld similarity index 77% rename from Architecture/i386/linker.ld rename to arch/i386/linker.ld index 4913e603..7e8cb44f 100644 --- a/Architecture/i386/linker.ld +++ b/arch/i386/linker.ld @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ OUTPUT_FORMAT(elf32-i386) diff --git a/Architecture/i386/MultipleAPICDescriptionTable.cpp b/arch/i386/madt.cpp similarity index 77% rename from Architecture/i386/MultipleAPICDescriptionTable.cpp rename to arch/i386/madt.cpp index f1176edf..61fcff86 100644 --- a/Architecture/i386/MultipleAPICDescriptionTable.cpp +++ b/arch/i386/madt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "acpi.hpp" diff --git a/Architecture/i386/Memory/VirtualMemoryManager.cpp b/arch/i386/memory/vmm.cpp similarity index 84% rename from Architecture/i386/Memory/VirtualMemoryManager.cpp rename to arch/i386/memory/vmm.cpp index d5c9da39..a286a37b 100644 --- a/Architecture/i386/Memory/VirtualMemoryManager.cpp +++ b/arch/i386/memory/vmm.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -168,20 +168,7 @@ namespace Memory PTE->Present = true; PTE->raw |= (uintptr_t)Flags; PTE->SetAddress((uintptr_t)PhysicalAddress >> 12); - -#if defined(a64) - CPU::x64::invlpg(VirtualAddress); -#elif defined(a32) CPU::x32::invlpg(VirtualAddress); -#elif defined(aa64) - asmv("dsb sy"); - asmv("tlbi vae1is, %0" - : - : "r"(VirtualAddress) - : "memory"); - asmv("dsb sy"); - asmv("isb"); -#endif #ifdef DEBUG /* https://stackoverflow.com/a/3208376/9352057 */ @@ -234,19 +221,6 @@ namespace Memory PTE.Present = false; PTEPtr->Entries[Index.PTEIndex] = PTE; - -#if defined(a64) - CPU::x64::invlpg(VirtualAddress); -#elif defined(a32) CPU::x32::invlpg(VirtualAddress); -#elif defined(aa64) - asmv("dsb sy"); - asmv("tlbi vae1is, %0" - : - : "r"(VirtualAddress) - : "memory"); - asmv("dsb sy"); - asmv("isb"); -#endif } } diff --git a/arch/i386/syscalls.cpp b/arch/i386/syscalls.cpp new file mode 100644 index 00000000..8e072ccd --- /dev/null +++ b/arch/i386/syscalls.cpp @@ -0,0 +1,30 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include + +#include "cpu/gdt.hpp" + +using namespace CPU::x32; + +extern "C" uint32_t SystemCallsHandler(SyscallsFrame *regs); + +void InitializeSystemCalls() +{ +} diff --git a/boot_logo.cpp b/boot_logo.cpp new file mode 100644 index 00000000..0b04ddb0 --- /dev/null +++ b/boot_logo.cpp @@ -0,0 +1,181 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "kernel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define STB_IMAGE_IMPLEMENTATION +#define STBI_NO_STDIO +#define STBI_NO_LINEAR +#define STBI_NO_THREAD_LOCALS +#define STBI_NO_HDR +#define STBI_ONLY_TGA +#include + +#include "mapi.hpp" +#include "Fex.hpp" + +using vfs::RefNode; + +/* Files: 0.tga 1.tga ... 26.tga */ +uint8_t *Frames[27]; +uint32_t FrameSizes[27]; +size_t FrameCount = 1; + +void BootLogoAnimationThread() +{ + char BootAnimPath[16]; + while (FrameCount < 27) + { + sprintf(BootAnimPath, "/etc/boot/%ld.tga", FrameCount); + RefNode *frame = fs->Open(BootAnimPath); + if (!frame) + { + debug("Failed to load boot animation frame %s", BootAnimPath); + break; + } + + FrameSizes[FrameCount] = s_cst(uint32_t, frame->Size); + Frames[FrameCount] = new uint8_t[frame->Size]; + frame->read(Frames[FrameCount], frame->Size); + delete frame; + FrameCount++; + } + + uint32_t DispX = Display->GetBuffer(1)->Width; + uint32_t DispY = Display->GetBuffer(1)->Height; + + for (size_t i = 1; i < FrameCount; i++) + { + int x, y, channels; + + if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], + &x, &y, &channels)) + continue; + + uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], + FrameSizes[i], &x, &y, + &channels, STBI_rgb_alpha); + + if (img == NULL) + continue; + + int offsetX = DispX / 2 - x / 2; + int offsetY = DispY / 2 - y / 2; + + for (int i = 0; i < x * y; i++) + { + uint32_t pixel = ((uint32_t *)img)[i]; + int r = (pixel >> 16) & 0xFF; + int g = (pixel >> 8) & 0xFF; + int b = (pixel >> 0) & 0xFF; + int a = (pixel >> 24) & 0xFF; + + if (a != 0xFF) + { + r = (r * a) / 0xFF; + g = (g * a) / 0xFF; + b = (b * a) / 0xFF; + } + + Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, + (r << 16) | (g << 8) | (b << 0), 1); + } + + free(img); + Display->SetBuffer(1); + TaskManager->Sleep(50); + } + + int brightness = 100; + while (brightness >= 0) + { + brightness -= 10; + Display->SetBrightness(brightness, 1); + Display->SetBuffer(1); + TaskManager->Sleep(5); + } +} + +void ExitLogoAnimationThread() +{ + Display->SetBrightness(100, 1); + Display->SetBuffer(1); + + /* Files: 26.tga 25.tga ... 1.tga */ + uint32_t DispX = Display->GetBuffer(1)->Width; + uint32_t DispY = Display->GetBuffer(1)->Height; + + for (size_t i = FrameCount - 1; i > 0; i--) + { + int x, y, channels; + + if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], + &x, &y, &channels)) + continue; + + uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], + FrameSizes[i], &x, &y, + &channels, STBI_rgb_alpha); + + if (img == NULL) + continue; + + int offsetX = DispX / 2 - x / 2; + int offsetY = DispY / 2 - y / 2; + + for (int i = 0; i < x * y; i++) + { + uint32_t pixel = ((uint32_t *)img)[i]; + int r = (pixel >> 16) & 0xFF; + int g = (pixel >> 8) & 0xFF; + int b = (pixel >> 0) & 0xFF; + int a = (pixel >> 24) & 0xFF; + + if (a != 0xFF) + { + r = (r * a) / 0xFF; + g = (g * a) / 0xFF; + b = (b * a) / 0xFF; + } + + Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, + (r << 16) | (g << 8) | (b << 0), 1); + } + + free(img); + Display->SetBuffer(1); + TaskManager->Sleep(50); + } + + int brightness = 100; + while (brightness >= 0) + { + brightness -= 10; + Display->SetBrightness(brightness, 1); + Display->SetBuffer(1); + TaskManager->Sleep(5); + } +} diff --git a/Core/AdvancedConfigurationAndPowerInterface.cpp b/core/acpi.cpp similarity index 87% rename from Core/AdvancedConfigurationAndPowerInterface.cpp rename to core/acpi.cpp index 5f5cf6ec..c6c7021d 100644 --- a/Core/AdvancedConfigurationAndPowerInterface.cpp +++ b/core/acpi.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/CPU.cpp b/core/cpu.cpp similarity index 90% rename from Core/CPU.cpp rename to core/cpu.cpp index 6b17476b..c3b1f9b1 100644 --- a/Core/CPU.cpp +++ b/core/cpu.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -112,13 +112,33 @@ namespace CPU return Hypervisor; #if defined(a64) uint32_t eax, ebx, ecx, edx; + x64::cpuid(0x1, &eax, &ebx, &ecx, &edx); + if (!(ecx & (1 << 31))) /* Intel & AMD are the same */ + { + Hypervisor[0] = 'N'; + Hypervisor[1] = 'o'; + Hypervisor[2] = 'n'; + Hypervisor[3] = 'e'; + return Hypervisor; + } + x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); memcpy(Hypervisor + 0, &ebx, 4); memcpy(Hypervisor + 4, &ecx, 4); memcpy(Hypervisor + 8, &edx, 4); #elif defined(a32) uint32_t eax, ebx, ecx, edx; - x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); + x32::cpuid(0x1, &eax, &ebx, &ecx, &edx); + if (!(ecx & (1 << 31))) /* Intel & AMD are the same */ + { + Hypervisor[0] = 'N'; + Hypervisor[1] = 'o'; + Hypervisor[2] = 'n'; + Hypervisor[3] = 'e'; + return Hypervisor; + } + + x32::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); memcpy(Hypervisor + 0, &ebx, 4); memcpy(Hypervisor + 4, &ecx, 4); memcpy(Hypervisor + 8, &edx, 4); diff --git a/Core/Crash/chfcts.hpp b/core/crash/chfcts.hpp similarity index 90% rename from Core/Crash/chfcts.hpp rename to core/crash/chfcts.hpp index 3c7ae735..fa620aeb 100644 --- a/Core/Crash/chfcts.hpp +++ b/core/crash/chfcts.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CRASH_HANDLERS_FUNCTIONS_H__ @@ -273,6 +273,8 @@ namespace CrashHandler class CrashKeyboardDriver : public Interrupts::Handler { private: + void PS2Wait(bool Read); + #if defined(a64) void OnInterruptReceived(CPU::x64::TrapFrame *Frame); #elif defined(a32) @@ -289,7 +291,6 @@ namespace CrashHandler void ArrowInput(uint8_t key); void UserInput(char *Input); - void HookKeyboard(); void DisplayMainScreen(CRData data); void DisplayDetailsScreen(CRData data); @@ -320,6 +321,7 @@ void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame); void VirtualizationExceptionHandler(CHArchTrapFrame *Frame); void SecurityExceptionHandler(CHArchTrapFrame *Frame); void UnknownExceptionHandler(CHArchTrapFrame *Frame); -void UserModeExceptionHandler(CHArchTrapFrame *Frame); + +bool UserModeExceptionHandler(CHArchTrapFrame *Frame); #endif // !__FENNIX_KERNEL_CRASH_HANDLERS_FUNCTIONS_H__ diff --git a/Core/Crash/CrashDetails.cpp b/core/crash/crash_details.cpp similarity index 94% rename from Core/Crash/CrashDetails.cpp rename to core/crash/crash_details.cpp index b66c9a28..9c7af0e3 100644 --- a/Core/Crash/CrashDetails.cpp +++ b/core/crash/crash_details.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../crashhandler.hpp" @@ -25,7 +25,7 @@ #include #if defined(a64) -#include "../../Architecture/amd64/cpu/gdt.hpp" +#include "../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif diff --git a/Core/Crash/CrashHandler.cpp b/core/crash/crash_handler.cpp similarity index 93% rename from Core/Crash/CrashHandler.cpp rename to core/crash/crash_handler.cpp index ebd21f24..5c5e2a9b 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/core/crash/crash_handler.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../crashhandler.hpp" @@ -31,16 +31,16 @@ #include #if defined(a64) -#include "../../Architecture/amd64/cpu/gdt.hpp" -#include "../Architecture/amd64/cpu/apic.hpp" +#include "../../arch/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/apic.hpp" #elif defined(a32) -#include "../../Architecture/i386/cpu/gdt.hpp" -#include "../Architecture/i386/cpu/apic.hpp" +#include "../../arch/i386/cpu/gdt.hpp" +#include "../arch/i386/cpu/apic.hpp" #elif defined(aa64) #endif #include "../../kernel.h" -#include "../../DAPI.hpp" +#include "../../mapi.hpp" NewLock(UserInputLock); @@ -50,6 +50,7 @@ namespace CrashHandler void *EHIntFrames[INT_FRAMES_MAX]; static bool ExceptionOccurred = false; int SBIdx = 255; + CrashKeyboardDriver *kbd; SafeFunction void printfWrapper(char c, void *unused) { @@ -335,7 +336,6 @@ namespace CrashHandler EHPrint("help - Display this help message.\n"); EHPrint("showbuf,sb - Display the contents of a screen buffer.\n"); EHPrint(" - A sleep timer will be enabled. This will cause the OS to sleep for an unknown amount of time.\n"); - EHPrint(" - \eFF4400WARNING: This can crash the system if a wrong buffer is selected.\eFAFAFA\n"); EHPrint("ifr - Show interrupt frames.\n"); EHPrint("tlb
- Print the page table entries\n"); EHPrint("bitmap - Print the memory bitmap\n"); @@ -343,7 +343,6 @@ namespace CrashHandler EHPrint("cr - Print the CPU control register\n"); EHPrint("tss - Print the CPU task state segment\n"); EHPrint("dump
- Dump memory\n"); - EHPrint(" - \eFF4400WARNING: This can crash the system if you try to read from an unmapped page.\eFAFAFA\n"); EHPrint("uartmemdmp - Dump the memory of a UART.\n"); EHPrint("main - Show the main screen.\n"); EHPrint("details - Show the details screen.\n"); @@ -661,10 +660,28 @@ namespace CrashHandler } else { - uint64_t Address = strtoul(addr, NULL, 16); + uintptr_t Address = strtoul(addr, NULL, 16); size_t Length = strtoul(len, NULL, 10); - debug("Dumping %ld bytes from %#lx\n", Length, Address); - EHDumpData((void *)Address, (unsigned long)Length); + + size_t ActualLength = Length; + uintptr_t AlignedAddress = ROUND_DOWN(Address, PAGE_SIZE); + { + Memory::Virtual vmm; + for (uintptr_t adr = AlignedAddress; + adr < Address + Length; + adr += PAGE_SIZE) + { + if (!vmm.Check((void *)adr)) + { + EHPrint("\eFFA500Address %#lx is not mapped\n", adr); + Display->SetBuffer(SBIdx); + ActualLength -= PAGE_SIZE; + } + } + } + + debug("Dumping %ld bytes from %#lx\n", ActualLength, AlignedAddress); + EHDumpData((void *)AlignedAddress, (unsigned long)ActualLength); } } else if (strncmp(Input, "uartmemdmp", 10) == 0) @@ -820,17 +837,22 @@ namespace CrashHandler EHIntFrames[i] = Interrupts::InterruptFrames[i]; PageFaultAddress = CPU::x64::readcr2().PFLA; - if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) + if (unlikely(Frame->cs != GDT_USER_CODE && + Frame->cs != GDT_USER_DATA)) { if (PageFaultAddress) { debug("Exception in kernel mode (ip: %#lx cr2: %#lx (%s))", - Frame->rip, PageFaultAddress, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->rip) : "No symbol"); + Frame->rip, PageFaultAddress, + KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->rip) + : "No symbol"); } else { debug("Exception in kernel mode (ip: %#lx (%s))", - Frame->rip, KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->rip) : "No symbol"); + Frame->rip, + KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->rip) + : "No symbol"); } CPUData *data = GetCurrentCPU(); @@ -853,51 +875,49 @@ namespace CrashHandler } else { + CPUData *data = GetCurrentCPU(); if (PageFaultAddress) { debug("Exception in user mode (ip: %#lx cr2: %#lx (%s))", Frame->rip, PageFaultAddress, - KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->rip) - : "No symbol"); + data->CurrentProcess->ELFSymbolTable + ? data->CurrentProcess->ELFSymbolTable->GetSymbolFromAddress(Frame->rip) + : "No symbol"); } else { debug("Exception in user mode (ip: %#lx (%s))", Frame->rip, - KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->rip) - : "No symbol"); + data->CurrentProcess->ELFSymbolTable + ? data->CurrentProcess->ELFSymbolTable->GetSymbolFromAddress(Frame->rip) + : "No symbol"); } - CPUData *data = GetCurrentCPU(); - if (!data) + + if (UserModeExceptionHandler(Frame)) + return; + + if (unlikely(data->CurrentThread->Security.IsCritical)) { + debug("Critical thread \"%s\"(%d) died", + data->CurrentThread->Name, + data->CurrentThread->ID); + if (TaskManager) + TaskManager->Panic(); ForceUnlock = true; Display->CreateBuffer(0, 0, SBIdx); StopAllCores(); - EHPrint("\eFF0000Cannot get CPU data! This results in a kernel crash!"); - error("Cannot get CPU data! This results in a kernel crash!"); - error("This should never happen!"); + return; } - else + + Tasking::TCB *tcb = data->CurrentThread; + Tasking::Task *ctx = tcb->GetContext(); + tcb->State = Tasking::Terminated; + tcb->ExitCode = Tasking::KILL_CRASH; + CPU::Interrupts(CPU::Enable); + while (true) { - debug("CPU %ld data is valid", data->ID); - if (data->CurrentThread->Security.IsCritical) - { - debug("Critical thread \"%s\"(%d) died", - data->CurrentThread->Name, - data->CurrentThread->ID); - if (TaskManager) - TaskManager->Panic(); - ForceUnlock = true; - Display->CreateBuffer(0, 0, SBIdx); - StopAllCores(); - } - else - { - debug("Current thread is valid %#lx", - data->CurrentThread.load()); - UserModeExceptionHandler(Frame); - return; - } + ctx->Yield(); + CPU::Halt(TaskManager->IsPanic()); } } #endif @@ -912,30 +932,32 @@ namespace CrashHandler if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) { + CPUData *data = GetCurrentCPU(); if (PageFaultAddress) { debug("Exception in kernel mode (ip: %#lx cr2: %#lx (%s))", Frame->eip, PageFaultAddress, - KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->eip) - : "No symbol"); + data->CurrentProcess->ELFSymbolTable + ? data->CurrentProcess->ELFSymbolTable->GetSymbolFromAddress(Frame->eip) + : "No symbol"); } else { debug("Exception in kernel mode (ip: %#lx (%s))", Frame->eip, - KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->eip) - : "No symbol"); + data->CurrentProcess->ELFSymbolTable + ? data->CurrentProcess->ELFSymbolTable->GetSymbolFromAddress(Frame->eip) + : "No symbol"); } - CPUData *data = GetCurrentCPU(); - if (data) + if (UserModeExceptionHandler(Frame)) + return; + + if (data->CurrentThread) { - if (data->CurrentThread) + if (!data->CurrentThread->Security.IsCritical) { - if (!data->CurrentThread->Security.IsCritical) - { - fixme("Exception in non-critical thread (kernel mode)"); - } + fixme("Exception in non-critical thread (kernel mode)"); } } @@ -947,6 +969,7 @@ namespace CrashHandler } else { + CPUData *data = GetCurrentCPU(); if (PageFaultAddress) { debug("Exception in user mode (ip: %#lx cr2: %#lx (%s))", @@ -961,37 +984,32 @@ namespace CrashHandler KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress(Frame->eip) : "No symbol"); } - CPUData *data = GetCurrentCPU(); - if (!data) + + if (UserModeExceptionHandler(Frame)) + return; + + if (unlikely(data->CurrentThread->Security.IsCritical)) { + debug("Critical thread \"%s\"(%d) died", + data->CurrentThread->Name, + data->CurrentThread->ID); + if (TaskManager) + TaskManager->Panic(); ForceUnlock = true; Display->CreateBuffer(0, 0, SBIdx); StopAllCores(); - EHPrint("\eFF0000Cannot get CPU data! This results in a kernel crash!"); - error("Cannot get CPU data! This results in a kernel crash!"); - error("This should never happen!"); + return; } - else + + Tasking::TCB *tcb = data->CurrentThread; + Tasking::Task *ctx = tcb->GetContext(); + tcb->State = Tasking::Terminated; + tcb->ExitCode = Tasking::KILL_CRASH; + CPU::Interrupts(CPU::Enable); + while (true) { - debug("CPU %ld data is valid", data->ID); - if (data->CurrentThread->Security.IsCritical) - { - debug("Critical thread \"%s\"(%d) died", - data->CurrentThread->Name, - data->CurrentThread->ID); - if (TaskManager) - TaskManager->Panic(); - ForceUnlock = true; - Display->CreateBuffer(0, 0, SBIdx); - StopAllCores(); - } - else - { - debug("Current thread is valid %#lx", - data->CurrentThread.load()); - UserModeExceptionHandler(Frame); - return; - } + ctx->Yield(); + CPU::Halt(TaskManager->IsPanic()); } } #endif @@ -1162,8 +1180,8 @@ namespace CrashHandler ExceptionOccurred = true; - if (DriverManager) - DriverManager->Panic(); + if (ModuleManager) + ModuleManager->Panic(); debug("Reading control registers..."); crashdata.Frame = Frame; @@ -1302,7 +1320,7 @@ namespace CrashHandler #elif defined(a32) error("FS=%#x GS=%#x CS=%#x DS=%#x", CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), - Frame->cs, ds); + Frame->cs, ds); error("EAX=%#x EBX=%#x ECX=%#x EDX=%#x", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); @@ -1378,9 +1396,10 @@ namespace CrashHandler DisplayTopOverlay(); DisplayMainScreen(crashdata); + Display->SetBuffer(255); + kbd = new CrashKeyboardDriver; DisplayBottomOverlay(); Display->SetBuffer(255); - HookKeyboard(); } else { diff --git a/Core/Crash/KBDrv.cpp b/core/crash/kb_drv.cpp similarity index 52% rename from Core/Crash/KBDrv.cpp rename to core/crash/kb_drv.cpp index 19cbdcb0..97017db9 100644 --- a/Core/Crash/KBDrv.cpp +++ b/core/crash/kb_drv.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../crashhandler.hpp" @@ -27,7 +27,7 @@ #include #if defined(a64) -#include "../../Architecture/amd64/cpu/gdt.hpp" +#include "../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif @@ -94,21 +94,151 @@ static inline int GetLetterFromScanCode(uint8_t ScanCode) namespace CrashHandler { + void CrashKeyboardDriver::PS2Wait(bool Read) + { + int Timeout = 100000; + uint8_t Status = 0; + while (Timeout--) + { + Status = inb(0x64); + if (Read) + { + if ((Status & 1) == 1) + return; + } + else + { + if ((Status & 2) == 0) + return; + } + } + } + CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */ { +#define WaitRead PS2Wait(true) +#define WaitWrite PS2Wait(false) + CPU::Interrupts(CPU::Disable); #if defined(a86) - while (inb(0x64) & 0x1) - inb(0x60); + // Disable devices + WaitWrite; + outb(0x64, 0xAD); + WaitWrite; + outb(0x64, 0xA7); - outb(0x64, 0xAE); + // Flush buffer + WaitRead; + inb(0x60); + + // outb(0x64, 0xAE); + + // Configure devices + WaitWrite; outb(0x64, 0x20); - uint8_t ret = (inb(0x60) | 1) & ~0x10; + WaitRead; + uint8_t cfg = inb(0x60); + bool DualChannel = cfg & 0b00100000; + if (DualChannel) + trace("Dual channel PS/2 controller detected."); + cfg |= 0b01000011; + WaitWrite; outb(0x64, 0x60); - outb(0x60, ret); - outb(0x60, 0xF4); + WaitWrite; + outb(0x60, cfg); - outb(0x21, 0xFD); - outb(0xA1, 0xFF); + WaitWrite; + outb(0x64, 0xAA); + WaitRead; + uint8_t test = inb(0x60); + if (test != 0x55) + { + error("PS/2 controller self test failed! (%#x)", test); + printf("PS/2 controller self test failed! (%#x)\n", test); + CPU::Stop(); + } + + WaitWrite; + outb(0x64, 0x60); + WaitWrite; + outb(0x60, cfg); + + bool DCExists = false; + if (DualChannel) + { + WaitWrite; + outb(0x64, 0xAE); + WaitWrite; + outb(0x64, 0x20); + WaitRead; + cfg = inb(0x60); + DCExists = !(cfg & 0b00100000); + WaitWrite; + outb(0x64, 0xAD); + debug("DCExists: %d", DCExists); + } + + WaitWrite; + outb(0x64, 0xAB); + WaitRead; + test = inb(0x60); + if (test != 0x00) + { + error("PS/2 keyboard self test failed! (%#x)", test); + printf("PS/2 keyboard self test failed! (%#x)\n", test); + CPU::Stop(); + } + + if (DCExists) + { + WaitWrite; + outb(0x64, 0xA9); + WaitRead; + test = inb(0x60); + if (test != 0x00) + { + error("PS/2 mouse self test failed! (%#x)", test); + printf("PS/2 mouse self test failed! (%#x)\n", test); + CPU::Stop(); + } + } + + WaitWrite; + outb(0x64, 0xAE); + + if (DCExists) + { + WaitWrite; + outb(0x64, 0xA8); + } + + WaitWrite; + outb(0x60, 0xFF); + WaitRead; + test = inb(0x60); + if (test == 0xFC) + { + error("PS/2 keyboard reset failed! (%#x)", test); + printf("PS/2 keyboard reset failed! (%#x)\n", test); + CPU::Stop(); + } + + WaitWrite; + outb(0x60, 0xD4); + WaitWrite; + outb(0x60, 0xFF); + WaitRead; + test = inb(0x60); + if (test == 0xFC) + { + error("PS/2 mouse reset failed! (%#x)", test); + printf("PS/2 mouse reset failed! (%#x)\n", test); + CPU::Stop(); + } + + // outb(0x60, 0xF4); + + // outb(0x21, 0xFD); + // outb(0xA1, 0xFF); #endif // defined(a86) CPU::Interrupts(CPU::Enable); @@ -180,12 +310,4 @@ namespace CrashHandler } #endif // a64 || a32 } - - SafeFunction void HookKeyboard() - { - CPU::Interrupts(CPU::Enable); - debug("Interrupts are enabled, waiting for user input"); - CrashKeyboardDriver kbd; /* We don't want to allocate memory. */ - CPU::Halt(true); - } } diff --git a/core/crash/screens/console.cpp b/core/crash/screens/console.cpp new file mode 100644 index 00000000..403a02d0 --- /dev/null +++ b/core/crash/screens/console.cpp @@ -0,0 +1,42 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../../crashhandler.hpp" +#include "../chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(a64) +#include "../../../arch/amd64/cpu/gdt.hpp" +#elif defined(a32) +#elif defined(aa64) +#endif + +#include "../../../kernel.h" + +namespace CrashHandler +{ + SafeFunction void DisplayConsoleScreen(CRData data) + { + EHPrint("TODO"); + UNUSED(data); + } +} \ No newline at end of file diff --git a/Core/Crash/Screens/Details.cpp b/core/crash/screens/details.cpp similarity index 94% rename from Core/Crash/Screens/Details.cpp rename to core/crash/screens/details.cpp index 28a0215d..322df1cc 100644 --- a/Core/Crash/Screens/Details.cpp +++ b/core/crash/screens/details.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../../crashhandler.hpp" @@ -25,7 +25,7 @@ #include #if defined(a64) -#include "../../../Architecture/amd64/cpu/gdt.hpp" +#include "../../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif diff --git a/Core/Crash/Screens/Main.cpp b/core/crash/screens/main.cpp similarity index 94% rename from Core/Crash/Screens/Main.cpp rename to core/crash/screens/main.cpp index a03f951c..4c9ca5fa 100644 --- a/Core/Crash/Screens/Main.cpp +++ b/core/crash/screens/main.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../../crashhandler.hpp" @@ -25,7 +25,7 @@ #include #if defined(a64) -#include "../../../Architecture/amd64/cpu/gdt.hpp" +#include "../../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif diff --git a/Core/Crash/Screens/StackFrame.cpp b/core/crash/screens/stack_frame.cpp similarity index 80% rename from Core/Crash/Screens/StackFrame.cpp rename to core/crash/screens/stack_frame.cpp index 0b23cf5b..80599f88 100644 --- a/Core/Crash/Screens/StackFrame.cpp +++ b/core/crash/screens/stack_frame.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../../crashhandler.hpp" @@ -26,7 +26,7 @@ #include #if defined(a64) -#include "../../../Architecture/amd64/cpu/gdt.hpp" +#include "../../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif diff --git a/Core/Crash/Screens/Tasks.cpp b/core/crash/screens/tasks.cpp similarity index 58% rename from Core/Crash/Screens/Tasks.cpp rename to core/crash/screens/tasks.cpp index c2f64f7b..83a4ad3e 100644 --- a/Core/Crash/Screens/Tasks.cpp +++ b/core/crash/screens/tasks.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../../crashhandler.hpp" @@ -25,7 +25,7 @@ #include #if defined(a64) -#include "../../../Architecture/amd64/cpu/gdt.hpp" +#include "../../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif @@ -36,22 +36,28 @@ namespace CrashHandler { SafeFunction void DisplayTasksScreen(CRData data) { - const char *StatusColor[7] = { + const char *StatusColor[9] = { "FF0000", // Unknown "AAFF00", // Ready "00AA00", // Running "FFAA00", // Sleeping "FFAA00", // Blocked + "FFAA00", // Stopped + "FFAA00", // Waiting + "FF0088", // Zombie "FF0000", // Terminated }; - const char *StatusString[7] = { - "Unknown", // Unknown - "Ready", // Ready - "Running", // Running - "Sleeping", // Sleeping - "Blocked", // Blocked + const char *StatusString[9] = { + "Unknown", // Unknown + "Ready", // Ready + "Running", // Running + "Sleeping", // Sleeping + "Blocked", // Blocked + "Stopped", // Stopped + "Waiting", // Waiting + "Zombie", // Zombie "Terminated", // Terminated }; @@ -74,14 +80,14 @@ namespace CrashHandler foreach (auto Process in Plist) { EHPrint("\e%s-> \eFAFAFA%s\eCCCCCC(%ld) \e00AAAA%s\eFAFAFA PT:\e00AAAA%#lx\n", - StatusColor[Process->Status.load()], Process->Name, - Process->ID, StatusString[Process->Status.load()], + StatusColor[Process->State.load()], Process->Name, + Process->ID, StatusString[Process->State.load()], Process->PageTable); foreach (auto Thread in Process->Threads) EHPrint("\e%s -> \eFAFAFA%s\eCCCCCC(%ld) \e00AAAA%s\eFAFAFA Stack:\e00AAAA%#lx\n", - StatusColor[Thread->Status.load()], Thread->Name, - Thread->ID, StatusString[Thread->Status.load()], + StatusColor[Thread->State.load()], Thread->Name, + Thread->ID, StatusString[Thread->State.load()], Thread->Stack); } } diff --git a/Core/Crash/SFrame.cpp b/core/crash/stack_frame.cpp similarity index 85% rename from Core/Crash/SFrame.cpp rename to core/crash/stack_frame.cpp index 026177f4..8cecea8c 100644 --- a/Core/Crash/SFrame.cpp +++ b/core/crash/stack_frame.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../crashhandler.hpp" @@ -25,7 +25,7 @@ #include #if defined(a64) -#include "../../Architecture/amd64/cpu/gdt.hpp" +#include "../../arch/amd64/cpu/gdt.hpp" #elif defined(a32) #elif defined(aa64) #endif diff --git a/core/crash/user_handler.cpp b/core/crash/user_handler.cpp new file mode 100644 index 00000000..886beb87 --- /dev/null +++ b/core/crash/user_handler.cpp @@ -0,0 +1,199 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../crashhandler.hpp" +#include "chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(a64) +#include "../../arch/amd64/cpu/gdt.hpp" +#elif defined(a32) +#elif defined(aa64) +#endif + +#include "../../kernel.h" + +SafeFunction bool UserModeExceptionHandler(CHArchTrapFrame *Frame) +{ + thisThread->State = Tasking::TaskState::Waiting; + CPUData *CurCPU = GetCurrentCPU(); + +#ifdef DEBUG + { +#if defined(a64) + CPU::x64::CR0 cr0 = CPU::x64::readcr0(); + CPU::x64::CR2 cr2 = CPU::x64::CR2{.PFLA = CrashHandler::PageFaultAddress}; + CPU::x64::CR3 cr3 = CPU::x64::readcr3(); + CPU::x64::CR4 cr4 = CPU::x64::readcr4(); + CPU::x64::CR8 cr8 = CPU::x64::readcr8(); + CPU::x64::EFER efer; + efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); + uintptr_t ds; + asmv("mov %%ds, %0" + : "=r"(ds)); +#elif defined(a32) + CPU::x32::CR0 cr0 = CPU::x32::readcr0(); + CPU::x32::CR2 cr2 = CPU::x32::CR2{.PFLA = CrashHandler::PageFaultAddress}; + CPU::x32::CR3 cr3 = CPU::x32::readcr3(); + CPU::x32::CR4 cr4 = CPU::x32::readcr4(); + CPU::x32::CR8 cr8 = CPU::x32::readcr8(); + uintptr_t ds; + asmv("mov %%ds, %0" + : "=r"(ds)); +#elif defined(aa64) +#endif + +#if defined(a64) + debug("FS=%#lx GS=%#lx SS=%#lx CS=%#lx DS=%#lx", + CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), + Frame->ss, Frame->cs, ds); + debug("R8=%#lx R9=%#lx R10=%#lx R11=%#lx", Frame->r8, Frame->r9, Frame->r10, Frame->r11); + debug("R12=%#lx R13=%#lx R14=%#lx R15=%#lx", Frame->r12, Frame->r13, Frame->r14, Frame->r15); + debug("RAX=%#lx RBX=%#lx RCX=%#lx RDX=%#lx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); + debug("RSI=%#lx RDI=%#lx RBP=%#lx RSP=%#lx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); + debug("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx EFER=%#lx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); +#elif defined(a32) + debug("FS=%#x GS=%#x CS=%#x DS=%#x", + CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), + Frame->cs, ds); + debug("EAX=%#x EBX=%#x ECX=%#x EDX=%#x", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); + debug("ESI=%#x EDI=%#x EBP=%#x ESP=%#x", Frame->esi, Frame->edi, Frame->ebp, Frame->esp); + debug("EIP=%#x EFL=%#x INT=%#x ERR=%#x", Frame->eip, Frame->eflags.raw, Frame->InterruptNumber, Frame->ErrorCode); +#elif defined(aa64) +#endif + +#if defined(a86) + debug("CR0=%#lx CR2=%#lx CR3=%#lx CR4=%#lx CR8=%#lx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); + + debug("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", + cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", + cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False", + cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", + cr0.Reserved0, cr0.Reserved1, cr0.Reserved2); + + debug("CR2: PFLA: %#lx", + cr2.PFLA); + + debug("CR3: PWT:%s PCD:%s PDBR:%#llx", + cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); +#endif // defined(a86) + +#if defined(a64) + debug("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", + cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", + cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", + cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", + cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", + cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", + cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); +#elif defined(a32) + debug("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x", + cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", + cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", + cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", + cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", + cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", + cr4.Reserved0, cr4.Reserved1); +#endif + +#if defined(a86) + debug("CR8: TPL:%d", cr8.TPL); +#endif // defined(a86) + +#if defined(a64) + debug("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", + Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", + Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", + Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", + Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", + Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, + Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); +#elif defined(a32) + debug("EFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x", + Frame->eflags.CF ? "True " : "False", Frame->eflags.PF ? "True " : "False", Frame->eflags.AF ? "True " : "False", Frame->eflags.ZF ? "True " : "False", + Frame->eflags.SF ? "True " : "False", Frame->eflags.TF ? "True " : "False", Frame->eflags.IF ? "True " : "False", Frame->eflags.DF ? "True " : "False", + Frame->eflags.OF ? "True " : "False", Frame->eflags.IOPL ? "True " : "False", Frame->eflags.NT ? "True " : "False", Frame->eflags.RF ? "True " : "False", + Frame->eflags.VM ? "True " : "False", Frame->eflags.AC ? "True " : "False", Frame->eflags.VIF ? "True " : "False", Frame->eflags.VIP ? "True " : "False", + Frame->eflags.ID ? "True " : "False", Frame->eflags.AlwaysOne, + Frame->eflags.Reserved0, Frame->eflags.Reserved1, Frame->eflags.Reserved2); +#elif defined(aa64) +#endif + +#if defined(a64) + debug("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", + efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", + efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", + efer.Reserved0, efer.Reserved1, efer.Reserved2); +#endif + } +#endif + + switch (Frame->InterruptNumber) + { + case CPU::x86::PageFault: + { + bool Handled = false; + + Handled = CurCPU->CurrentProcess->vma->HandleCoW(CrashHandler::PageFaultAddress); + if (!Handled) + Handled = CurCPU->CurrentThread->Stack->Expand(CrashHandler::PageFaultAddress); + + if (Handled) + { + debug("Page fault handled"); + thisThread->State = Tasking::TaskState::Ready; + return true; + } + + break; + } + case CPU::x86::DivideByZero: + case CPU::x86::Debug: + case CPU::x86::NonMaskableInterrupt: + case CPU::x86::Breakpoint: + case CPU::x86::Overflow: + case CPU::x86::BoundRange: + case CPU::x86::InvalidOpcode: + case CPU::x86::DeviceNotAvailable: + case CPU::x86::DoubleFault: + case CPU::x86::CoprocessorSegmentOverrun: + case CPU::x86::InvalidTSS: + case CPU::x86::SegmentNotPresent: + case CPU::x86::StackSegmentFault: + case CPU::x86::GeneralProtectionFault: + case CPU::x86::x87FloatingPoint: + case CPU::x86::AlignmentCheck: + case CPU::x86::MachineCheck: + case CPU::x86::SIMDFloatingPoint: + case CPU::x86::Virtualization: + case CPU::x86::Security: + default: + { + error("Unhandled exception %d on CPU %d", + Frame->InterruptNumber, CurCPU->ID); + break; + } + } + + error("User mode exception handler failed"); + return false; +} diff --git a/core/crashhandler.hpp b/core/crashhandler.hpp new file mode 100644 index 00000000..66dabfb8 --- /dev/null +++ b/core/crashhandler.hpp @@ -0,0 +1,35 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_CRASH_HANDLER_H__ +#define __FENNIX_KERNEL_CRASH_HANDLER_H__ + +#include + +#include +#include + +namespace CrashHandler +{ + extern uintptr_t PageFaultAddress; + extern void *EHIntFrames[INT_FRAMES_MAX]; + + void EHPrint(const char *Format, ...); + void Handle(void *Data); +} + +#endif // !__FENNIX_KERNEL_CRASH_HANDLER_H__ diff --git a/Core/Debugger.cpp b/core/debugger.cpp similarity index 68% rename from Core/Debugger.cpp rename to core/debugger.cpp index 3af8ffe7..e7df1174 100644 --- a/Core/Debugger.cpp +++ b/core/debugger.cpp @@ -1,33 +1,71 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include -#include #include #include +#include NewLock(DebuggerLock); -using namespace UniversalAsynchronousReceiverTransmitter; +extern bool serialports[8]; static inline NIF void uart_wrapper(char c, void *unused) { - UART(COM1).Write(c); + static int once = 0; + if (unlikely(!once++)) + { + uint8_t com = inb(0x3F8); + if (com != 0xFF) + { + outb(s_cst(uint16_t, 0x3F8 + 1), 0x00); // Disable all interrupts + outb(s_cst(uint16_t, 0x3F8 + 3), 0x80); // Enable DLAB (set baud rate divisor) + outb(s_cst(uint16_t, 0x3F8 + 0), 0x1); // Set divisor to 1 (lo byte) 115200 baud + outb(s_cst(uint16_t, 0x3F8 + 1), 0x0); // (hi byte) + outb(s_cst(uint16_t, 0x3F8 + 3), 0x03); // 8 bits, no parity, one stop bit + outb(s_cst(uint16_t, 0x3F8 + 2), 0xC7); // Enable FIFO, clear them, with 14-byte threshold + outb(s_cst(uint16_t, 0x3F8 + 4), 0x0B); // IRQs enabled, RTS/DSR set + + /* FIXME https://wiki.osdev.org/Serial_Ports */ + // outb(s_cst(uint16_t, 0x3F8 + 0), 0x1E); + // outb(s_cst(uint16_t, 0x3F8 + 0), 0xAE); + // Check if the serial port is faulty. + // if (inb(s_cst(uint16_t, 0x3F8 + 0)) != 0xAE) + // { + // static int once = 0; + // if (!once++) + // warn("Serial port %#llx is faulty.", 0x3F8); + // // serialports[0x3F8] = false; // ignore for now + // // return; + // } + + // Set to normal operation mode. + outb(s_cst(uint16_t, 0x3F8 + 4), 0x0F); + serialports[0] = true; + } + } + + if (likely(serialports[0])) + { + while ((inb(s_cst(uint16_t, 0x3F8 + 5)) & 0x20) == 0) + ; + outb(0x3F8, c); + } UNUSED(unused); } diff --git a/core/disk.cpp b/core/disk.cpp new file mode 100644 index 00000000..aa0b69e4 --- /dev/null +++ b/core/disk.cpp @@ -0,0 +1,192 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +#include "../kernel.h" +#include "../mapi.hpp" +#include "../Fex.hpp" + +namespace Disk +{ + void Manager::FetchDisks(unsigned long modUniqueID) + { + KernelCallback callback{}; + callback.Reason = QueryReason; + ModuleManager->IOCB(modUniqueID, &callback); + this->AvailablePorts = callback.DiskCallback.Fetch.Ports; + this->BytesPerSector = callback.DiskCallback.Fetch.BytesPerSector; + debug("AvailablePorts:%ld BytesPerSector:%ld", this->AvailablePorts, this->BytesPerSector); + + if (this->AvailablePorts <= 0) + return; + + uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector + 1)); + + for (unsigned char ItrPort = 0; ItrPort < this->AvailablePorts; ItrPort++) + { + Drive *drive = new Drive{}; + sprintf(drive->Name, "sd%ld", modUniqueID); + debug("Drive Name: %s", drive->Name); + // TODO: Implement disk type detection. Very useful in the future. + drive->MechanicalDisk = true; + + memset(RWBuffer, 0, this->BytesPerSector); + callback.Reason = ReceiveReason; + callback.DiskCallback.RW = { + .Sector = 0, + .SectorCount = 2, + .Port = ItrPort, + .Buffer = RWBuffer, + .Write = false, + }; + ModuleManager->IOCB(modUniqueID, &callback); + memcpy(&drive->Table, RWBuffer, sizeof(PartitionTable)); + + /* + TODO: Add to devfs the disk + */ + + if (drive->Table.GPT.Signature == GPT_MAGIC) + { + drive->Style = GPT; + uint32_t Entries = 512 / drive->Table.GPT.EntrySize; + uint32_t Sectors = drive->Table.GPT.PartCount / Entries; + for (uint32_t Block = 0; Block < Sectors; Block++) + { + memset(RWBuffer, 0, this->BytesPerSector); + callback.Reason = ReceiveReason; + callback.DiskCallback.RW = { + .Sector = 2 + Block, + .SectorCount = 1, + .Port = ItrPort, + .Buffer = RWBuffer, + .Write = false, + }; + ModuleManager->IOCB(modUniqueID, &callback); + + for (uint32_t e = 0; e < Entries; e++) + { + GUIDPartitionTableEntry GPTPartition = reinterpret_cast(RWBuffer)[e]; + if (memcmp(GPTPartition.PartitionType, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(GPTPartition.PartitionType)) != 0) + { + debug("Partition Type: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + GPTPartition.PartitionType[0], GPTPartition.PartitionType[1], GPTPartition.PartitionType[2], GPTPartition.PartitionType[3], + GPTPartition.PartitionType[4], GPTPartition.PartitionType[5], GPTPartition.PartitionType[6], GPTPartition.PartitionType[7], + GPTPartition.PartitionType[8], GPTPartition.PartitionType[9], GPTPartition.PartitionType[10], GPTPartition.PartitionType[11], + GPTPartition.PartitionType[12], GPTPartition.PartitionType[13], GPTPartition.PartitionType[14], GPTPartition.PartitionType[15]); + + debug("Unique Partition GUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + GPTPartition.UniquePartitionGUID[0], GPTPartition.UniquePartitionGUID[1], GPTPartition.UniquePartitionGUID[2], GPTPartition.UniquePartitionGUID[3], + GPTPartition.UniquePartitionGUID[4], GPTPartition.UniquePartitionGUID[5], GPTPartition.UniquePartitionGUID[6], GPTPartition.UniquePartitionGUID[7], + GPTPartition.UniquePartitionGUID[8], GPTPartition.UniquePartitionGUID[9], GPTPartition.UniquePartitionGUID[10], GPTPartition.UniquePartitionGUID[11], + GPTPartition.UniquePartitionGUID[12], GPTPartition.UniquePartitionGUID[13], GPTPartition.UniquePartitionGUID[14], GPTPartition.UniquePartitionGUID[15]); + + Partition *partition = new Partition{}; + memset(partition->Label, '\0', sizeof(partition->Label)); + // TODO: Add support for UTF-16 partition names. + /* Convert utf16 to utf8 */ + for (int i = 0; i < 36; i++) + { + uint16_t utf16 = GPTPartition.PartitionName[i]; + if (utf16 == 0) + break; + if (utf16 < 0x80) + partition->Label[i] = (char)utf16; + else if (utf16 < 0x800) + { + partition->Label[i] = (char)(0xC0 | (utf16 >> 6)); + partition->Label[i + 1] = (char)(0x80 | (utf16 & 0x3F)); + i++; + } + else + { + partition->Label[i] = (char)(0xE0 | (utf16 >> 12)); + partition->Label[i + 1] = (char)(0x80 | ((utf16 >> 6) & 0x3F)); + partition->Label[i + 2] = (char)(0x80 | (utf16 & 0x3F)); + i += 2; + } + } + partition->StartLBA = GPTPartition.FirstLBA; + partition->EndLBA = GPTPartition.LastLBA; + partition->Sectors = (size_t)(partition->EndLBA - partition->StartLBA); + partition->Port = ItrPort; + partition->Flags = Present; + partition->Style = GPT; + if (GPTPartition.Attributes & 1) + partition->Flags |= EFISystemPartition; + partition->Index = drive->Partitions.size(); + trace("GPT partition \"%s\" found with %lld sectors", + partition->Label, partition->Sectors); + drive->Partitions.push_back(partition); + + char PartitionName[64]; + sprintf(PartitionName, "sd%ldp%ld", drives.size(), partition->Index); + fixme("PartitionName: %s", PartitionName); + + /* + TODO: Add to devfs the disk + */ + } + } + } + trace("%d GPT partitions found.", drive->Partitions.size()); + } + else if (drive->Table.MBR.Signature[0] == MBR_MAGIC0 && + drive->Table.MBR.Signature[1] == MBR_MAGIC1) + { + drive->Style = MBR; + for (size_t p = 0; p < 4; p++) + if (drive->Table.MBR.Partitions[p].LBAFirst != 0) + { + Partition *partition = new Partition{}; + partition->StartLBA = drive->Table.MBR.Partitions[p].LBAFirst; + partition->EndLBA = drive->Table.MBR.Partitions[p].LBAFirst + drive->Table.MBR.Partitions[p].Sectors; + partition->Sectors = drive->Table.MBR.Partitions[p].Sectors; + partition->Port = ItrPort; + partition->Flags = Present; + partition->Style = MBR; + partition->Index = drive->Partitions.size(); + trace("MBR Partition %x found with %d sectors.", + drive->Table.MBR.UniqueID, partition->Sectors); + drive->Partitions.push_back(partition); + + char PartitionName[64]; + sprintf(PartitionName, "sd%ldp%ld", drives.size(), partition->Index); + fixme("PartitionName: %s", PartitionName); + + /* + TODO: Add to devfs the disk + */ + } + trace("%d MBR partitions found.", drive->Partitions.size()); + } + else + warn("No partition table found on port %d!", ItrPort); + + drives.push_back(drive); + } + + KernelAllocator.FreePages(RWBuffer, TO_PAGES(this->BytesPerSector + 1)); + } + + Manager::Manager() {} + Manager::~Manager() {} +} diff --git a/Core/DifferentiatedSystemDescriptionTable.cpp b/core/dsdt.cpp similarity index 89% rename from Core/DifferentiatedSystemDescriptionTable.cpp rename to core/dsdt.cpp index d285b69a..6bc302bc 100644 --- a/Core/DifferentiatedSystemDescriptionTable.cpp +++ b/core/dsdt.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -23,9 +23,9 @@ #include #if defined(a64) -#include "../Architecture/amd64/cpu/apic.hpp" +#include "../arch/amd64/cpu/apic.hpp" #elif defined(a32) -#include "../Architecture/i386/cpu/apic.hpp" +#include "../arch/i386/cpu/apic.hpp" #endif #include "../kernel.h" diff --git a/Core/InterruptsManager.cpp b/core/interrupts_manager.cpp similarity index 79% rename from Core/InterruptsManager.cpp rename to core/interrupts_manager.cpp index a996ea12..e3299fad 100644 --- a/Core/InterruptsManager.cpp +++ b/core/interrupts_manager.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -24,13 +24,13 @@ #include #if defined(a64) -#include "../Architecture/amd64/cpu/apic.hpp" -#include "../Architecture/amd64/cpu/gdt.hpp" -#include "../Architecture/amd64/cpu/idt.hpp" +#include "../arch/amd64/cpu/apic.hpp" +#include "../arch/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/idt.hpp" #elif defined(a32) -#include "../Architecture/i386/cpu/apic.hpp" -#include "../Architecture/i386/cpu/gdt.hpp" -#include "../Architecture/i386/cpu/idt.hpp" +#include "../arch/i386/cpu/apic.hpp" +#include "../arch/i386/cpu/gdt.hpp" +#include "../arch/i386/cpu/idt.hpp" #elif defined(aa64) #endif @@ -153,7 +153,9 @@ namespace Interrupts #endif // debug("IRQ%ld", Frame->InterruptNumber - 32); - memmove(InterruptFrames + 1, InterruptFrames, sizeof(InterruptFrames) - sizeof(InterruptFrames[0])); + memmove(InterruptFrames + 1, + InterruptFrames, + sizeof(InterruptFrames) - sizeof(InterruptFrames[0])); #if defined(a64) InterruptFrames[0] = (void *)Frame->rip; #elif defined(a32) @@ -192,7 +194,8 @@ namespace Interrupts if (!InterruptHandled) { - error("IRQ%d is unhandled on CPU %d.", Frame->InterruptNumber - 32, Core); + error("IRQ%d is unhandled on CPU %d.", + Frame->InterruptNumber - 32, Core); if (Frame->InterruptNumber == CPU::x86::IRQ1) { uint8_t scancode = inb(0x60); @@ -228,18 +231,22 @@ namespace Interrupts { if (ev.ID == InterruptNumber) { - warn("IRQ%d is already registered.", InterruptNumber); + warn("IRQ%d is already registered.", + InterruptNumber); } } - debug("Registering interrupt handler for IRQ%d.", InterruptNumber); + debug("Registering interrupt handler for IRQ%d.", + InterruptNumber); + this->InterruptNumber = InterruptNumber; RegisteredEvents.push_back({InterruptNumber, this}); } Handler::~Handler() { - debug("Unregistering interrupt handler for IRQ%d.", this->InterruptNumber); + debug("Unregistering interrupt handler for IRQ%d.", + this->InterruptNumber); forItr(itr, RegisteredEvents) { @@ -255,15 +262,18 @@ namespace Interrupts #if defined(a64) void Handler::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { - trace("Unhandled interrupt IRQ%d", Frame->InterruptNumber - 32); + trace("Unhandled interrupt IRQ%d", + Frame->InterruptNumber - 32); #elif defined(a32) void Handler::OnInterruptReceived(CPU::x32::TrapFrame *Frame) { - trace("Unhandled interrupt received"); + trace("Unhandled interrupt IRQ%d", + Frame->InterruptNumber - 32); #elif defined(aa64) void Handler::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) { - trace("Unhandled interrupt received"); + trace("Unhandled interrupt IRQ%d", + Frame->InterruptNumber); #endif } } diff --git a/Core/Lock.cpp b/core/lock.cpp similarity index 90% rename from Core/Lock.cpp rename to core/lock.cpp index 7c12dc17..1d20e521 100644 --- a/Core/Lock.cpp +++ b/core/lock.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/core/memory/brk.cpp b/core/memory/brk.cpp new file mode 100644 index 00000000..83a6813a --- /dev/null +++ b/core/memory/brk.cpp @@ -0,0 +1,94 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace Memory +{ + void *ProgramBreak::brk(void *Address) + { + if (HeapStart == 0x0 || Break == 0x0) + { + error("HeapStart or Break is 0x0"); + return (void *)-EAGAIN; + } + + /* Get the current program break. */ + if (Address == nullptr) + return (void *)Break; + + /* Check if the address is valid. */ + if ((uintptr_t)Address < HeapStart) + return (void *)-ENOMEM; + + Virtual vmm = Virtual(this->Table); + + if ((uintptr_t)Address > Break) + { + /* Allocate more memory. */ + size_t Pages = TO_PAGES(uintptr_t(Address) - Break); + void *Allocated = vma->RequestPages(Pages); + if (Allocated == nullptr) + return (void *)-ENOMEM; + + /* Map the allocated pages. */ + for (size_t i = 0; i < Pages; i++) + { + void *VirtAddr = (void *)(Break + (i * PAGE_SIZE)); + void *PhysAddr = (void *)(uintptr_t(Allocated) + (i * PAGE_SIZE)); + vmm.Map(VirtAddr, PhysAddr, RW | US); + } + + Break = (uint64_t)Address; + return (void *)Break; + } + + /* Free memory. */ + size_t Pages = TO_PAGES(uintptr_t(Address) - Break); + vma->FreePages((void *)Break, Pages); + + /* Unmap the freed pages. */ + for (size_t i = 0; i < Pages; i++) + { + uint64_t Page = Break - (i * 0x1000); + vmm.Remap((void *)Page, (void *)Page, PTFlag::P | PTFlag::RW); + } + + Break = (uint64_t)Address; + return (void *)Break; + } + + ProgramBreak::ProgramBreak(PageTable *Table, VirtualMemoryArea *vma) + { + assert(Table != nullptr); + assert(vma != nullptr); + + this->Table = Table; + this->vma = vma; + } + + ProgramBreak::~ProgramBreak() + { + /* Do nothing because VirtualMemoryArea + will be destroyed later. */ + } +} diff --git a/core/memory/find_bitmap_region.cpp b/core/memory/find_bitmap_region.cpp new file mode 100644 index 00000000..06f02106 --- /dev/null +++ b/core/memory/find_bitmap_region.cpp @@ -0,0 +1,212 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#ifdef DEBUG +#include +#endif + +#include "../../kernel.h" + +namespace Memory +{ + __no_sanitize("alignment") void Physical::FindBitmapRegion(uintptr_t &BitmapAddress, + size_t &BitmapAddressSize) + { + size_t BitmapSize = (size_t)(bInfo.Memory.Size / PAGE_SIZE) / 8 + 1; + + uintptr_t KernelStart = (uintptr_t)bInfo.Kernel.PhysicalBase; + uintptr_t KernelEnd = (uintptr_t)bInfo.Kernel.PhysicalBase + bInfo.Kernel.Size; + + uintptr_t SectionsStart = 0x0; + uintptr_t SectionsEnd = 0x0; + + uintptr_t Symbols = 0x0; + uintptr_t StringAddress = 0x0; + size_t SymbolSize = 0; + size_t StringSize = 0; + + uintptr_t RSDPStart = 0x0; + uintptr_t RSDPEnd = 0x0; + + if (bInfo.Kernel.Symbols.Num && + bInfo.Kernel.Symbols.EntSize && + bInfo.Kernel.Symbols.Shndx) + { + char *sections = r_cst(char *, bInfo.Kernel.Symbols.Sections); + + SectionsStart = (uintptr_t)sections; + SectionsEnd = (uintptr_t)sections + bInfo.Kernel.Symbols.EntSize * + bInfo.Kernel.Symbols.Num; + + for (size_t i = 0; i < bInfo.Kernel.Symbols.Num; ++i) + { + Elf_Shdr *sym = (Elf_Shdr *)§ions[bInfo.Kernel.Symbols.EntSize * i]; + Elf_Shdr *str = (Elf_Shdr *)§ions[bInfo.Kernel.Symbols.EntSize * + sym->sh_link]; + + if (sym->sh_type == SHT_SYMTAB && + str->sh_type == SHT_STRTAB) + { + Symbols = (uintptr_t)sym->sh_addr; + StringAddress = (uintptr_t)str->sh_addr; + SymbolSize = (size_t)sym->sh_size; + StringSize = (size_t)str->sh_size; + break; + } + } + } + +#if defined(a86) + if (bInfo.RSDP) + { + RSDPStart = (uintptr_t)bInfo.RSDP; + RSDPEnd = (uintptr_t)bInfo.RSDP + sizeof(BootInfo::RSDPInfo); + +#ifdef DEBUG + ACPI::ACPI::ACPIHeader *ACPIPtr; + bool XSDT = false; + + if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress) + { + ACPIPtr = (ACPI::ACPI::ACPIHeader *)bInfo.RSDP->XSDTAddress; + XSDT = true; + } + else + ACPIPtr = (ACPI::ACPI::ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress; + + if (Memory::Virtual().Check(ACPIPtr)) + { + size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / + (XSDT ? 8 : 4)); + debug("There are %d ACPI tables", TableSize); + } +#endif + } +#elif defined(aa64) +#endif + + for (uint64_t i = 0; i < bInfo.Memory.Entries; i++) + { + if (bInfo.Memory.Entry[i].Type == Usable) + { + uintptr_t RegionAddress = (uintptr_t)bInfo.Memory.Entry[i].BaseAddress; + uintptr_t RegionSize = bInfo.Memory.Entry[i].Length; + + /* We don't want to use the first 1MB of memory. */ + if (RegionAddress <= 0xFFFFF) + continue; + + if ((BitmapSize + 0x100) > RegionSize) + { + debug("Region %p-%p (%d MiB) is too small for bitmap.", + (void *)RegionAddress, + (void *)(RegionAddress + RegionSize), + TO_MiB(RegionSize)); + continue; + } + + BitmapAddress = RegionAddress; + BitmapAddressSize = RegionSize; + + struct AddrRange + { + uintptr_t Start; + uintptr_t End; + }; + + auto SortAddresses = [](AddrRange *Array, size_t n) + { + size_t MinimumIndex; + for (size_t i = 0; i < n - 1; i++) + { + MinimumIndex = i; + for (size_t j = i + 1; j < n; j++) + if (Array[j].Start < Array[MinimumIndex].Start) + MinimumIndex = j; + + AddrRange tmp = Array[MinimumIndex]; + Array[MinimumIndex] = Array[i]; + Array[i] = tmp; + } + }; + + AddrRange PtrArray[] = + { + {KernelStart, + KernelEnd}, + {SectionsStart, + SectionsEnd}, + {Symbols, + Symbols + SymbolSize}, + {StringAddress, + StringAddress + StringSize}, + {RSDPStart, + RSDPEnd}, + {(uintptr_t)bInfo.Kernel.FileBase, + (uintptr_t)bInfo.Kernel.FileBase + bInfo.Kernel.Size}, + {(uintptr_t)bInfo.Modules[0].Address, + (uintptr_t)bInfo.Modules[0].Address + bInfo.Modules[0].Size}, + {(uintptr_t)bInfo.Modules[1].Address, + (uintptr_t)bInfo.Modules[1].Address + bInfo.Modules[1].Size}, + {(uintptr_t)bInfo.Modules[2].Address, + (uintptr_t)bInfo.Modules[2].Address + bInfo.Modules[2].Size}, + {(uintptr_t)bInfo.Modules[3].Address, + (uintptr_t)bInfo.Modules[3].Address + bInfo.Modules[3].Size}, + /* MAX_MODULES == 4 */ + }; + + SortAddresses(PtrArray, sizeof(PtrArray) / sizeof(PtrArray[0])); + + for (size_t i = 0; i < sizeof(PtrArray) / sizeof(PtrArray[0]); i++) + { + if (PtrArray[i].Start == 0x0) + continue; + + uintptr_t Start = PtrArray[i].Start; + uintptr_t End = PtrArray[i].End; + debug("%#lx - %#lx", Start, End); + + if (RegionAddress >= Start && + End <= (RegionAddress + RegionSize)) + { + BitmapAddress = End; + BitmapAddressSize = RegionSize - (End - RegionAddress); + } + } + + if ((BitmapSize + 0x100) > BitmapAddressSize) + { + debug("Region %p-%p (%d MiB) is too small for bitmap.", + (void *)BitmapAddress, + (void *)(BitmapAddress + BitmapAddressSize), + TO_MiB(BitmapAddressSize)); + continue; + } + + debug("Found free memory for bitmap: %p (%d MiB)", + (void *)BitmapAddress, + TO_MiB(BitmapAddressSize)); + break; + } + } + } +} diff --git a/Core/Memory/HeapAllocators/Xalloc/README.md b/core/memory/heap_allocators/Xalloc/README.md similarity index 100% rename from Core/Memory/HeapAllocators/Xalloc/README.md rename to core/memory/heap_allocators/Xalloc/README.md diff --git a/core/memory/heap_allocators/Xalloc/Wrapper.cpp b/core/memory/heap_allocators/Xalloc/Wrapper.cpp new file mode 100644 index 00000000..2e4a393e --- /dev/null +++ b/core/memory/heap_allocators/Xalloc/Wrapper.cpp @@ -0,0 +1,40 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "Xalloc.hpp" + +#include + +extern "C" void *Xalloc_REQUEST_PAGES(Xsize_t Pages) +{ + return KernelAllocator.RequestPages(Pages); +} + +extern "C" void Xalloc_FREE_PAGES(void *Address, Xsize_t Pages) +{ + KernelAllocator.FreePages(Address, Pages); +} + +extern "C" void Xalloc_MAP_MEMORY(void *VirtualAddress, void *PhysicalAddress, Xsize_t Flags) +{ + Memory::Virtual(KernelPageTable).Map(VirtualAddress, PhysicalAddress, Flags); +} + +extern "C" void Xalloc_UNMAP_MEMORY(void *VirtualAddress) +{ + Memory::Virtual(KernelPageTable).Unmap(VirtualAddress); +} diff --git a/Core/Memory/HeapAllocators/Xalloc/Xalloc.hpp b/core/memory/heap_allocators/Xalloc/Xalloc.hpp similarity index 88% rename from Core/Memory/HeapAllocators/Xalloc/Xalloc.hpp rename to core/memory/heap_allocators/Xalloc/Xalloc.hpp index 9fee2393..44cdbc98 100644 --- a/Core/Memory/HeapAllocators/Xalloc/Xalloc.hpp +++ b/core/memory/heap_allocators/Xalloc/Xalloc.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_Xalloc_H__ diff --git a/Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp b/core/memory/heap_allocators/Xalloc/XallocV1.cpp similarity index 89% rename from Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp rename to core/memory/heap_allocators/Xalloc/XallocV1.cpp index 23fcc97f..bc38d1ff 100644 --- a/Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp +++ b/core/memory/heap_allocators/Xalloc/XallocV1.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "Xalloc.hpp" diff --git a/Core/Memory/HeapAllocators/Xalloc/XallocV2.cpp b/core/memory/heap_allocators/Xalloc/XallocV2.cpp similarity index 88% rename from Core/Memory/HeapAllocators/Xalloc/XallocV2.cpp rename to core/memory/heap_allocators/Xalloc/XallocV2.cpp index 15063bcd..be829ae2 100644 --- a/Core/Memory/HeapAllocators/Xalloc/XallocV2.cpp +++ b/core/memory/heap_allocators/Xalloc/XallocV2.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "Xalloc.hpp" diff --git a/Core/Memory/HeapAllocators/liballoc_1_1/liballoc_1_1.c b/core/memory/heap_allocators/liballoc_1_1/liballoc_1_1.c similarity index 100% rename from Core/Memory/HeapAllocators/liballoc_1_1/liballoc_1_1.c rename to core/memory/heap_allocators/liballoc_1_1/liballoc_1_1.c diff --git a/Core/Memory/HeapAllocators/liballoc_1_1/liballoc_1_1.h b/core/memory/heap_allocators/liballoc_1_1/liballoc_1_1.h similarity index 100% rename from Core/Memory/HeapAllocators/liballoc_1_1/liballoc_1_1.h rename to core/memory/heap_allocators/liballoc_1_1/liballoc_1_1.h diff --git a/Core/Memory/HeapAllocators/liballoc_1_1/liballoc_hooks.cpp b/core/memory/heap_allocators/liballoc_1_1/liballoc_hooks.cpp similarity index 100% rename from Core/Memory/HeapAllocators/liballoc_1_1/liballoc_hooks.cpp rename to core/memory/heap_allocators/liballoc_1_1/liballoc_hooks.cpp diff --git a/Core/Memory/Memory.cpp b/core/memory/memory.cpp similarity index 94% rename from Core/Memory/Memory.cpp rename to core/memory/memory.cpp index db59db76..d3dc459f 100644 --- a/Core/Memory/Memory.cpp +++ b/core/memory/memory.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -24,8 +24,8 @@ #include #endif -#include "HeapAllocators/Xalloc/Xalloc.hpp" -#include "HeapAllocators/liballoc_1_1/liballoc_1_1.h" +#include "heap_allocators/Xalloc/Xalloc.hpp" +#include "heap_allocators/liballoc_1_1/liballoc_1_1.h" #include "../../kernel.h" // #define DEBUG_ALLOCATIONS 1 diff --git a/Core/Memory/PageTable.cpp b/core/memory/page_table.cpp similarity index 100% rename from Core/Memory/PageTable.cpp rename to core/memory/page_table.cpp diff --git a/Core/Memory/PageMapIndexer.cpp b/core/memory/pmi.cpp similarity index 52% rename from Core/Memory/PageMapIndexer.cpp rename to core/memory/pmi.cpp index 98270e6e..9d9c3ddd 100644 --- a/Core/Memory/PageMapIndexer.cpp +++ b/core/memory/pmi.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/core/memory/pmm.cpp similarity index 72% rename from Core/Memory/PhysicalMemoryManager.cpp rename to core/memory/pmm.cpp index e95f84f7..b9258e36 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/core/memory/pmm.cpp @@ -1,23 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include +#include #include +#include #ifdef DEBUG #include #endif @@ -325,85 +327,13 @@ namespace Memory uintptr_t BitmapAddress = 0x0; size_t BitmapAddressSize = 0; - uintptr_t KernelStart = (uintptr_t)bInfo.Kernel.PhysicalBase; - uintptr_t KernelEnd = (uintptr_t)bInfo.Kernel.PhysicalBase + bInfo.Kernel.Size; - - for (uint64_t i = 0; i < bInfo.Memory.Entries; i++) - { - if (bInfo.Memory.Entry[i].Type == Usable) - { - uintptr_t RegionAddress = (uintptr_t)bInfo.Memory.Entry[i].BaseAddress; - uintptr_t RegionSize = bInfo.Memory.Entry[i].Length; - - /* We don't want to use the first 1MB of memory. */ - if (RegionAddress <= 0xFFFFF) - continue; - - if ((BitmapSize + 0x100) > RegionSize) - { - debug("Region %p-%p (%d MiB) is too small for bitmap.", - (void *)RegionAddress, - (void *)(RegionAddress + RegionSize), - TO_MiB(RegionSize)); - continue; - } - - BitmapAddress = RegionAddress; - BitmapAddressSize = RegionSize; - - if (RegionAddress >= KernelStart && KernelEnd <= (RegionAddress + RegionSize)) - { - BitmapAddress = KernelEnd; - BitmapAddressSize = RegionSize - (KernelEnd - RegionAddress); - } - - if ((BitmapSize + 0x100) > BitmapAddressSize) - { - debug("Region %p-%p (%d MiB) is too small for bitmap.", - (void *)RegionAddress, - (void *)(RegionAddress + BitmapAddressSize), - TO_MiB(BitmapAddressSize)); - continue; - } - - for (size_t i = 0; i < MAX_MODULES; i++) - { - uintptr_t ModuleStart = (uintptr_t)bInfo.Modules[i].Address; - uintptr_t ModuleEnd = (uintptr_t)bInfo.Modules[i].Address + bInfo.Modules[i].Size; - - if (ModuleStart == 0x0) - break; - - if (RegionAddress >= ModuleStart && ModuleEnd <= (RegionAddress + RegionSize)) - { - BitmapAddress = ModuleEnd; - BitmapAddressSize = RegionSize - (ModuleEnd - RegionAddress); - } - } - - if ((BitmapSize + 0x100) > BitmapAddressSize) - { - debug("Region %p-%p (%d MiB) is too small for bitmap.", - (void *)BitmapAddress, - (void *)(BitmapAddress + BitmapAddressSize), - TO_MiB(BitmapAddressSize)); - continue; - } - - debug("Found free memory for bitmap: %p (%d MiB)", - (void *)BitmapAddress, - TO_MiB(BitmapAddressSize)); - break; - } - } - + FindBitmapRegion(BitmapAddress, BitmapAddressSize); if (BitmapAddress == 0x0) { error("No free memory found!"); CPU::Stop(); } - /* TODO: Read swap config and make the configure the bitmap size correctly */ debug("Initializing Bitmap at %p-%p (%d Bytes)", BitmapAddress, (void *)(BitmapAddress + BitmapSize), diff --git a/Core/Memory/ReserveEssentials.cpp b/core/memory/reserve_essentials.cpp similarity index 79% rename from Core/Memory/ReserveEssentials.cpp rename to core/memory/reserve_essentials.cpp index 0ce86d0f..08e60787 100644 --- a/Core/Memory/ReserveEssentials.cpp +++ b/core/memory/reserve_essentials.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -78,10 +78,17 @@ namespace Memory bInfo.Kernel.Symbols.EntSize && bInfo.Kernel.Symbols.Shndx) { - char *sections = reinterpret_cast(bInfo.Kernel.Symbols.Sections); - uint8_t *StringAddress = nullptr; + char *sections = r_cst(char *, bInfo.Kernel.Symbols.Sections); + debug("Reserving sections region %#lx-%#lx...", + sections, + (void *)((uintptr_t)sections + bInfo.Kernel.Symbols.EntSize * + bInfo.Kernel.Symbols.Num)); + + this->ReservePages(sections, TO_PAGES(bInfo.Kernel.Symbols.EntSize * + bInfo.Kernel.Symbols.Num)); Elf_Sym *Symbols = nullptr; + uint8_t *StringAddress = nullptr; #if defined(a64) || defined(aa64) Elf64_Xword SymbolSize = 0; @@ -104,8 +111,10 @@ namespace Memory StringAddress = (uint8_t *)str->sh_addr; SymbolSize = (int)sym->sh_size; StringSize = (int)str->sh_size; - debug("Symbol table found, %d entries", - SymbolSize / sym->sh_entsize); + debug("Symbol table found, %d entries (%ld KiB)", + SymbolSize / sym->sh_entsize, + TO_KiB(SymbolSize)); + this->ReservePages(Symbols, TO_PAGES(SymbolSize)); break; } } @@ -148,12 +157,12 @@ namespace Memory this->ReservePages(bInfo.RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo))); - ACPI::ACPI::ACPIHeader *ACPIPtr = nullptr; + ACPI::ACPI::ACPIHeader *ACPIPtr; bool XSDT = false; if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress) { - ACPIPtr = (ACPI::ACPI::ACPIHeader *)(bInfo.RSDP->XSDTAddress); + ACPIPtr = (ACPI::ACPI::ACPIHeader *)bInfo.RSDP->XSDTAddress; XSDT = true; } else diff --git a/core/memory/smart_heap.cpp b/core/memory/smart_heap.cpp new file mode 100644 index 00000000..ef954b47 --- /dev/null +++ b/core/memory/smart_heap.cpp @@ -0,0 +1,25 @@ +#include + +namespace Memory +{ + SmartHeap::SmartHeap(size_t Size, VirtualMemoryArea *vma) + { + if (vma) + { + this->vma = vma; + this->Object = vma->RequestPages(TO_PAGES(Size)); + } + else + this->Object = kmalloc(Size); + this->ObjectSize = Size; + memset(this->Object, 0, Size); + } + + SmartHeap::~SmartHeap() + { + if (this->vma) + this->vma->FreePages(this->Object, TO_PAGES(this->ObjectSize)); + else + kfree(this->Object); + } +} diff --git a/core/memory/stack_guard.cpp b/core/memory/stack_guard.cpp new file mode 100644 index 00000000..30995b84 --- /dev/null +++ b/core/memory/stack_guard.cpp @@ -0,0 +1,171 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include + +namespace Memory +{ + bool StackGuard::Expand(uintptr_t FaultAddress) + { + if (this->UserMode) + { + if (FaultAddress < (uintptr_t)this->StackBottom - 0x100 || + FaultAddress > (uintptr_t)this->StackTop) + { + info("Fault address %#lx is not in range of stack %#lx - %#lx", FaultAddress, + (uintptr_t)this->StackBottom - 0x100, (uintptr_t)this->StackTop); + return false; /* It's not about the stack. */ + } + else + { + void *AllocatedStack = this->vma->RequestPages(TO_PAGES(USER_STACK_SIZE) + 1); + debug("AllocatedStack: %#lx", AllocatedStack); + memset(AllocatedStack, 0, USER_STACK_SIZE); + + Virtual vmm = Virtual(this->vma->GetTable()); + for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) + { + void *VirtualPage = (void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)); + void *PhysicalPage = (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)); + + vmm.Map(VirtualPage, PhysicalPage, PTFlag::RW | PTFlag::US); + AllocatedPages ap = { + .PhysicalAddress = PhysicalPage, + .VirtualAddress = VirtualPage, + }; + AllocatedPagesList.push_back(ap); + debug("Mapped %#lx to %#lx", PhysicalPage, VirtualPage); + } + + this->StackBottom = (void *)((uintptr_t)this->StackBottom - USER_STACK_SIZE); + this->Size += USER_STACK_SIZE; + debug("Stack expanded to %#lx", this->StackBottom); + this->Expanded = true; + return true; + } + } + else + { + fixme("Not implemented and probably not needed"); + return false; + } + } + + void StackGuard::Fork(StackGuard *Parent) + { + this->UserMode = Parent->GetUserMode(); + this->StackBottom = Parent->GetStackBottom(); + this->StackTop = Parent->GetStackTop(); + this->StackPhysicalBottom = Parent->GetStackPhysicalBottom(); + this->StackPhysicalTop = Parent->GetStackPhysicalTop(); + this->Size = Parent->GetSize(); + this->Expanded = Parent->IsExpanded(); + + if (this->UserMode) + { + std::vector ParentAllocatedPages = Parent->GetAllocatedPages(); + Virtual vma = Virtual(this->vma->GetTable()); + foreach (auto Page in ParentAllocatedPages) + { + void *NewPhysical = this->vma->RequestPages(1); + debug("Forking address %#lx to %#lx", Page.PhysicalAddress, NewPhysical); + memcpy(NewPhysical, Page.PhysicalAddress, PAGE_SIZE); + vma.Map(Page.VirtualAddress, NewPhysical, PTFlag::RW | PTFlag::US); + + AllocatedPages ap = { + .PhysicalAddress = NewPhysical, + .VirtualAddress = Page.VirtualAddress, + }; + AllocatedPagesList.push_back(ap); + debug("Mapped %#lx to %#lx", NewPhysical, Page.VirtualAddress); + } + } + else + { + fixme("Kernel mode stack fork not implemented"); + } + } + + StackGuard::StackGuard(bool User, VirtualMemoryArea *vma) + { + this->UserMode = User; + this->vma = vma; + + if (this->UserMode) + { + void *AllocatedStack = vma->RequestPages(TO_PAGES(USER_STACK_SIZE) + 1); + memset(AllocatedStack, 0, USER_STACK_SIZE); + debug("AllocatedStack: %#lx", AllocatedStack); + + { + Virtual vmm = Virtual(vma->GetTable()); + for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) + { + void *VirtualPage = (void *)(USER_STACK_BASE + (i * PAGE_SIZE)); + void *PhysicalPage = (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)); + vmm.Map(VirtualPage, PhysicalPage, PTFlag::RW | PTFlag::US); + + AllocatedPages ap = { + .PhysicalAddress = PhysicalPage, + .VirtualAddress = VirtualPage, + }; + AllocatedPagesList.push_back(ap); + debug("Mapped %#lx to %#lx", PhysicalPage, VirtualPage); + } + } + + this->StackBottom = (void *)USER_STACK_BASE; + this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE); + + this->StackPhysicalBottom = AllocatedStack; + this->StackPhysicalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE); + + this->Size = USER_STACK_SIZE; + } + else + { + this->StackBottom = vma->RequestPages(TO_PAGES(STACK_SIZE) + 1); + memset(this->StackBottom, 0, STACK_SIZE); + debug("StackBottom: %#lx", this->StackBottom); + + this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE); + + this->StackPhysicalBottom = this->StackBottom; + this->StackPhysicalTop = this->StackTop; + + this->Size = STACK_SIZE; + + for (size_t i = 0; i < TO_PAGES(STACK_SIZE); i++) + { + AllocatedPages pa = { + .PhysicalAddress = (void *)((uintptr_t)this->StackBottom + (i * PAGE_SIZE)), + .VirtualAddress = (void *)((uintptr_t)this->StackBottom + (i * PAGE_SIZE)), + }; + AllocatedPagesList.push_back(pa); + } + } + + debug("Allocated stack at %#lx", this->StackBottom); + } + + StackGuard::~StackGuard() + { + /* VMA will free the stack */ + } +} diff --git a/core/memory/vma.cpp b/core/memory/vma.cpp new file mode 100644 index 00000000..78c533be --- /dev/null +++ b/core/memory/vma.cpp @@ -0,0 +1,331 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include + +#include "../../kernel.h" + +namespace Memory +{ + // ReadFSFunction(MEM_Read) + // { + // if (Size <= 0) + // Size = node->Length; + + // if (RefOffset > node->Length) + // return 0; + + // if ((node->Length - RefOffset) == 0) + // return 0; /* EOF */ + + // if (RefOffset + (off_t)Size > node->Length) + // Size = node->Length; + + // memcpy(Buffer, (uint8_t *)(node->Address + RefOffset), Size); + // return Size; + // } + + // WriteFSFunction(MEM_Write) + // { + // if (Size <= 0) + // Size = node->Length; + + // if (RefOffset > node->Length) + // return 0; + + // if (RefOffset + (off_t)Size > node->Length) + // Size = node->Length; + + // memcpy((uint8_t *)(node->Address + RefOffset), Buffer, Size); + // return Size; + // } + + // vfs::FileSystemOperations mem_op = { + // .Name = "mem", + // .Read = MEM_Read, + // .Write = MEM_Write, + // }; + + uint64_t VirtualMemoryArea::GetAllocatedMemorySize() + { + SmartLock(MgrLock); + uint64_t Size = 0; + foreach (auto ap in AllocatedPagesList) + Size += ap.PageCount; + return FROM_PAGES(Size); + } + + bool VirtualMemoryArea::Add(void *Address, size_t Count) + { + SmartLock(MgrLock); + if (Address == nullptr) + { + error("Address is null!"); + return false; + } + + if (Count == 0) + { + error("Count is 0!"); + return false; + } + + for (size_t i = 0; i < AllocatedPagesList.size(); i++) + { + if (AllocatedPagesList[i].Address == Address) + { + error("Address already exists!"); + return false; + } + else if ((uintptr_t)Address < (uintptr_t)AllocatedPagesList[i].Address) + { + if ((uintptr_t)Address + (Count * PAGE_SIZE) > (uintptr_t)AllocatedPagesList[i].Address) + { + error("Address intersects with an allocated page!"); + return false; + } + } + else + { + if ((uintptr_t)AllocatedPagesList[i].Address + (AllocatedPagesList[i].PageCount * PAGE_SIZE) > (uintptr_t)Address) + { + error("Address intersects with an allocated page!"); + return false; + } + } + } + + AllocatedPagesList.push_back({Address, Count}); + return true; + } + + void *VirtualMemoryArea::RequestPages(size_t Count, bool User) + { + SmartLock(MgrLock); + void *Address = KernelAllocator.RequestPages(Count); + for (size_t i = 0; i < Count; i++) + { + int Flags = Memory::PTFlag::RW; + if (User) + Flags |= Memory::PTFlag::US; + + void *AddressToMap = (void *)((uintptr_t)Address + (i * PAGE_SIZE)); + + Memory::Virtual vmm = Memory::Virtual(this->Table); + vmm.Remap(AddressToMap, AddressToMap, Flags); + } + + AllocatedPagesList.push_back({Address, Count}); + + /* For security reasons, we clear the allocated page + if it's a user page. */ + if (User) + memset(Address, 0, Count * PAGE_SIZE); + + return Address; + } + + void VirtualMemoryArea::FreePages(void *Address, size_t Count) + { + SmartLock(MgrLock); + forItr(itr, AllocatedPagesList) + { + if (itr->Address == Address) + { + /** TODO: Advanced checks. Allow if the page count is less than the requested one. + * This will allow the user to free only a part of the allocated pages. + * + * But this will be in a separate function because we need to specify if we + * want to free from the start or from the end and return the new address. + */ + if (itr->PageCount != Count) + { + error("Page count mismatch! (Allocated: %lld, Requested: %lld)", itr->PageCount, Count); + return; + } + + KernelAllocator.FreePages(Address, Count); + + Memory::Virtual vmm = Memory::Virtual(this->Table); + for (size_t i = 0; i < Count; i++) + { + void *AddressToMap = (void *)((uintptr_t)Address + (i * PAGE_SIZE)); + vmm.Remap(AddressToMap, AddressToMap, Memory::PTFlag::RW); + // vmm.Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE))); + } + AllocatedPagesList.erase(itr); + return; + } + } + } + + void VirtualMemoryArea::DetachAddress(void *Address) + { + SmartLock(MgrLock); + forItr(itr, AllocatedPagesList) + { + if (itr->Address == Address) + { + AllocatedPagesList.erase(itr); + return; + } + } + } + + void *VirtualMemoryArea::CreateCoWRegion(void *Address, + size_t Length, + bool Read, bool Write, bool Exec, + bool Fixed, bool Shared) + { + Memory::Virtual vmm = Memory::Virtual(this->Table); + + // FIXME + // for (uintptr_t j = uintptr_t(Address); + // j < uintptr_t(Address) + Length; + // j += PAGE_SIZE) + // { + // if (vmm.Check((void *)j, Memory::G)) + // { + // if (Fixed) + // return (void *)-EINVAL; + // Address = (void *)(j + PAGE_SIZE); + // } + // } + + bool AnyAddress = Address == nullptr; + + if (AnyAddress) + { + Address = this->RequestPages(1); + if (Address == nullptr) + return nullptr; + memset(Address, 0, PAGE_SIZE); + } + + vmm.Unmap(Address, Length); + vmm.Map(Address, nullptr, Length, PTFlag::CoW); + + if (AnyAddress) + vmm.Remap(Address, Address, PTFlag::RW | PTFlag::US); + + SharedRegion sr{ + .Address = Address, + .Read = Read, + .Write = Write, + .Exec = Exec, + .Fixed = Fixed, + .Shared = Shared, + .Length = Length, + .ReferenceCount = 0, + }; + SharedRegions.push_back(sr); + return Address; + } + + bool VirtualMemoryArea::HandleCoW(uintptr_t PFA) + { + function("%#lx", PFA); + Memory::Virtual vmm = Memory::Virtual(this->Table); + Memory::PageTableEntry *pte = vmm.GetPTE((void *)PFA); + + if (!pte) + { + /* Unmapped page */ + debug("PTE is null!"); + return false; + } + + if (pte->CopyOnWrite == true) + { + foreach (auto sr in SharedRegions) + { + uintptr_t Start = (uintptr_t)sr.Address; + uintptr_t End = (uintptr_t)sr.Address + sr.Length; + + if (PFA >= Start && PFA < End) + { + if (sr.Shared) + { + fixme("Shared CoW"); + return false; + } + else + { + void *pAddr = this->RequestPages(1); + if (pAddr == nullptr) + return false; + memset(pAddr, 0, PAGE_SIZE); + + uint64_t Flags = 0; + if (sr.Read) + Flags |= PTFlag::US; + if (sr.Write) + Flags |= PTFlag::RW; + // if (sr.Exec) + // Flags |= PTFlag::XD; + + vmm.Remap((void *)PFA, pAddr, Flags); + pte->CopyOnWrite = false; + return true; + } + } + } + } + + debug("PFA %#lx is not CoW", PFA); + return false; + } + + VirtualMemoryArea::VirtualMemoryArea(PageTable *Table) + { + debug("+ %#lx %s", this, + KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : ""); + + SmartLock(MgrLock); + if (Table) + this->Table = Table; + else + { + if (TaskManager) + this->Table = thisProcess->PageTable; + else +#if defined(a64) + this->Table = (PageTable *)CPU::x64::readcr3().raw; +#elif defined(a32) + this->Table = (PageTable *)CPU::x32::readcr3().raw; +#endif + } + } + + VirtualMemoryArea::~VirtualMemoryArea() + { + debug("- %#lx %s", this, + KernelSymbolTable ? KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_return_address(0)) : ""); + SmartLock(MgrLock); + foreach (auto ap in AllocatedPagesList) + { + KernelAllocator.FreePages(ap.Address, ap.PageCount); + Memory::Virtual vmm = Memory::Virtual(this->Table); + for (size_t i = 0; i < ap.PageCount; i++) + vmm.Remap((void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), + (void *)((uintptr_t)ap.Address + (i * PAGE_SIZE)), + Memory::PTFlag::RW); + } + } +} diff --git a/core/memory/vmm.cpp b/core/memory/vmm.cpp new file mode 100644 index 00000000..1d99fcaf --- /dev/null +++ b/core/memory/vmm.cpp @@ -0,0 +1,34 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +namespace Memory +{ + Virtual::Virtual(PageTable *Table) + { + if (Table) + this->Table = Table; + else + this->Table = (PageTable *)CPU::PageTable(); + } + + Virtual::~Virtual() {} +} diff --git a/core/module/api.hpp b/core/module/api.hpp new file mode 100644 index 00000000..85981986 --- /dev/null +++ b/core/module/api.hpp @@ -0,0 +1,27 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MODULE_API_H__ +#define __FENNIX_KERNEL_MODULE_API_H__ + +#include + +#include "../../mapi.hpp" + +extern KernelAPI KernelAPITemplate; + +#endif // !__FENNIX_KERNEL_MODULE_API_H__ diff --git a/core/module/module.cpp b/core/module/module.cpp new file mode 100644 index 00000000..1f3e47a3 --- /dev/null +++ b/core/module/module.cpp @@ -0,0 +1,347 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "../../modules/mod.hpp" +#include "../../kernel.h" +#include "../../mapi.hpp" +#include "../../Fex.hpp" +#include "api.hpp" + +using vfs::RefNode; + +namespace Module +{ + void Module::Panic() + { + debug("%ld modules loaded, [modUIDs: %ld]", Modules.size(), modUIDs - 1); + + foreach (auto Drv in Modules) + { + KernelCallback callback{}; + callback.Reason = StopReason; + ModuleManager->IOCB(Drv.modUniqueID, &callback); + + for (size_t j = 0; j < sizeof(Drv.InterruptHook) / sizeof(Drv.InterruptHook[0]); j++) + { + if (!Drv.InterruptHook[j]) + continue; + + Drv.InterruptHook[j]->Disable(); + debug("Interrupt hook %#lx disabled", Drv.InterruptHook[j]); + } + } + } + + void Module::UnloadAllModules() + { + debug("%ld modules loaded, [modUIDs: %ld]", Modules.size(), modUIDs - 1); + + foreach (auto Drv in Modules) + { + KernelCallback callback{}; + callback.Reason = StopReason; + debug("Stopping & unloading module %ld [%#lx]", Drv.modUniqueID, Drv.Address); + ModuleManager->IOCB(Drv.modUniqueID, &callback); + + for (size_t j = 0; j < sizeof(Drv.InterruptHook) / sizeof(Drv.InterruptHook[0]); j++) + { + if (!Drv.InterruptHook[j]) + continue; + + debug("Interrupt hook %#lx", Drv.InterruptHook[j]); + delete Drv.InterruptHook[j], Drv.InterruptHook[j] = nullptr; + } + + if (Drv.vma) + delete Drv.vma, Drv.vma = nullptr; + } + Modules.clear(); + } + + bool Module::UnloadModule(unsigned long id) + { + debug("Searching for module %ld", id); + + forItr(Drv, Modules) + { + if (Drv->modUniqueID != id) + continue; + + KernelCallback callback{}; + callback.Reason = StopReason; + debug("Stopping & unloading module %ld [%#lx]", Drv->modUniqueID, Drv->Address); + this->IOCB(Drv->modUniqueID, &callback); + + for (size_t j = 0; j < sizeof(Drv->InterruptHook) / sizeof(Drv->InterruptHook[0]); j++) + { + if (!Drv->InterruptHook[j]) + continue; + + debug("Interrupt hook %#lx", Drv->InterruptHook[j]); + delete Drv->InterruptHook[j], Drv->InterruptHook[j] = nullptr; + } + + if (Drv->vma) + delete Drv->vma, Drv->vma = nullptr; + + Modules.erase(Drv); + return true; + } + return false; + } + + int Module::IOCB(unsigned long id, void *KCB) + { + foreach (auto Drv in Modules) + { + if (Drv.modUniqueID != id) + continue; + + FexExtended *fexE = (FexExtended *)Drv.ExtendedHeaderAddress; + return ((int (*)(void *))((uintptr_t)fexE->Module.Callback + (uintptr_t)Drv.Address))(KCB); + } + return -1; + } + + ModuleCode Module::CallModuleEntryPoint(void *fex, bool BuiltIn) + { + ModuleCode ret{}; + KernelAPI modKAPI = KernelAPITemplate; + + modKAPI.Info.modUniqueID = modUIDs++; + modKAPI.Info.KernelDebug = DebuggerIsAttached; + + debug("Calling module entry point ( %#lx %ld )", (unsigned long)fex, modKAPI.Info.modUniqueID); + + if (!BuiltIn) + { + modKAPI.Info.Offset = (unsigned long)fex; + + debug("MODULE: %s HAS MODULE ID %ld", + ((FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS))->Module.Name, + modKAPI.Info.modUniqueID); + ret = ((ModuleCode(*)(KernelAPI *))((uintptr_t)((Fex *)fex)->EntryPoint + (uintptr_t)fex))(((KernelAPI *)&modKAPI)); + } + else + { + debug("MODULE: BUILTIN HAS MODULE ID %ld", modKAPI.Info.modUniqueID); + ret = ((ModuleCode(*)(KernelAPI *))((uintptr_t)fex))(((KernelAPI *)&modKAPI)); + } + + if (ModuleCode::OK != ret) + { + modUIDs--; + return ret; + } + return ModuleCode::OK; + } + + ModuleCode Module::LoadModule(vfs::Node *fildes) + { + Fex DrvHdr; + fildes->read((uint8_t *)&DrvHdr, sizeof(Fex), 0); + + if (DrvHdr.Magic[0] != 'F' || DrvHdr.Magic[1] != 'E' || DrvHdr.Magic[2] != 'X' || DrvHdr.Magic[3] != '\0') + return ModuleCode::INVALID_FEX_HEADER; + + debug("Fex Magic: \"%s\"; Type: %d; OS: %d; EntryPoint: %#lx", DrvHdr.Magic, DrvHdr.Type, DrvHdr.OS, DrvHdr.EntryPoint); + + if (DrvHdr.Type != FexFormatType::FexFormatType_Module) + return ModuleCode::NOT_MODULE; + + FexExtended fexE; + fildes->read((uint8_t *)&fexE, sizeof(FexExtended), EXTENDED_SECTION_ADDRESS); + + debug("Name: \"%s\"; Type: %d; Callback: %#lx", fexE.Module.Name, fexE.Module.Type, fexE.Module.Callback); + + Memory::SmartHeap ModuleAddress(fildes->Size); + fildes->read(ModuleAddress, fildes->Size, 0); + + switch (fexE.Module.Bind.Type) + { + case ModuleBindType::BIND_PCI: + return this->ModuleLoadBindPCI(ModuleAddress, fildes->Size); + case ModuleBindType::BIND_INTERRUPT: + return this->ModuleLoadBindInterrupt(ModuleAddress, fildes->Size); + case ModuleBindType::BIND_PROCESS: + return this->ModuleLoadBindProcess(ModuleAddress, fildes->Size); + case ModuleBindType::BIND_INPUT: + return this->ModuleLoadBindInput(ModuleAddress, fildes->Size); + default: + { + error("Unknown module bind type: %d", fexE.Module.Bind.Type); + return ModuleCode::UNKNOWN_MODULE_BIND_TYPE; + } + } + } + + void Module::LoadModules() + { + SmartCriticalSection(ModuleInitLock); + + const char *ModuleConfigFile = new char[256]; + assert(strlen(Config.ModuleDirectory) < 255 - 12); + strcpy((char *)ModuleConfigFile, Config.ModuleDirectory); + strcat((char *)ModuleConfigFile, "/config.ini"); + fixme("Loading module config file: %s", ModuleConfigFile); + delete[] ModuleConfigFile; + + debug("Loading built-in modules"); + StartBuiltInModules(); + + RefNode *ModuleDirectory = fs->Open(Config.ModuleDirectory); + if (!ModuleDirectory) + { + KPrint("\eE85230Failed to open %s: %d)", + Config.ModuleDirectory, errno); + return; + } + + debug("Loading modules from %s", Config.ModuleDirectory); + foreach (auto DrvFile in ModuleDirectory->node->Children) + { + if (DrvFile->Type != vfs::NodeType::FILE) + continue; + + if (cwk_path_has_extension(DrvFile->Name)) + { + const char *extension; + size_t extension_length; + cwk_path_get_extension(DrvFile->Name, &extension, &extension_length); + debug("File: %s; Extension: %s", DrvFile->Name, extension); + if (strcmp(extension, ".fex") == 0) + { + uintptr_t ret = this->LoadModule(DrvFile); + char *RetString = new char[256]; + if (ret == ModuleCode::OK) + strcpy(RetString, "\e058C19OK"); + else if (ret == ModuleCode::NOT_AVAILABLE) + strcpy(RetString, "\eFF7900NOT AVAILABLE"); + else + strcpy(RetString, "\eE85230FAILED"); + KPrint("%s %s %#lx", DrvFile->Name, RetString, ret); + delete[] RetString; + } + } + } + delete ModuleDirectory; + } + + Module::Module() {} + + Module::~Module() + { + debug("Destructor called"); + this->UnloadAllModules(); + } + +#if defined(a64) + SafeFunction void ModuleInterruptHook::OnInterruptReceived(CPU::x64::TrapFrame *Frame) +#elif defined(a32) + SafeFunction void ModuleInterruptHook::OnInterruptReceived(CPU::x32::TrapFrame *Frame) +#elif defined(aa64) + SafeFunction void ModuleInterruptHook::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) +#endif + { + SmartLock(DriverInterruptLock); /* Lock in case of multiple interrupts firing at the same time */ + if (!this->Enabled) + { + debug("Interrupt hook is not enabled (%#lx, IRQ%d)", + Frame->InterruptNumber, + Frame->InterruptNumber - 32); + return; + } + + if (!Handle.InterruptCallback) + { +#if defined(a86) + uint64_t IntNum = Frame->InterruptNumber - 32; +#elif defined(aa64) + uint64_t IntNum = Frame->InterruptNumber; +#endif + warn("Interrupt callback for %ld is not set for module %ld!", + IntNum, Handle.modUniqueID); + return; + } + CPURegisters regs; +#if defined(a64) + regs.r15 = Frame->r15; + regs.r14 = Frame->r14; + regs.r13 = Frame->r13; + regs.r12 = Frame->r12; + regs.r11 = Frame->r11; + regs.r10 = Frame->r10; + regs.r9 = Frame->r9; + regs.r8 = Frame->r8; + + regs.rbp = Frame->rbp; + regs.rdi = Frame->rdi; + regs.rsi = Frame->rsi; + regs.rdx = Frame->rdx; + regs.rcx = Frame->rcx; + regs.rbx = Frame->rbx; + regs.rax = Frame->rax; + + regs.InterruptNumber = Frame->InterruptNumber; + regs.ErrorCode = Frame->ErrorCode; + regs.rip = Frame->rip; + regs.cs = Frame->cs; + regs.rflags = Frame->rflags.raw; + regs.rsp = Frame->rsp; + regs.ss = Frame->ss; +#elif defined(a32) + regs.edi = Frame->edi; + regs.esi = Frame->esi; + regs.ebp = Frame->ebp; + regs.esp = Frame->esp; + regs.ebx = Frame->ebx; + regs.edx = Frame->edx; + regs.ecx = Frame->ecx; + regs.eax = Frame->eax; + + regs.InterruptNumber = Frame->InterruptNumber; + regs.ErrorCode = Frame->ErrorCode; + regs.eip = Frame->eip; + regs.cs = Frame->cs; + regs.eflags = Frame->eflags.raw; + regs.r3_esp = Frame->r3_esp; + regs.r3_ss = Frame->r3_ss; +#elif defined(aa64) +#endif + ((int (*)(void *))(Handle.InterruptCallback))(®s); + UNUSED(Frame); + } + + ModuleInterruptHook::ModuleInterruptHook(int Interrupt, ModuleFile Handle) : Interrupts::Handler(Interrupt) + { + this->Handle = Handle; +#if defined(a86) + trace("Interrupt %d hooked to module %ld", Interrupt, Handle.modUniqueID); +#elif defined(aa64) + trace("Interrupt %d hooked to module %ld", Interrupt, Handle.modUniqueID); +#endif + } +} diff --git a/core/module/module_api.cpp b/core/module/module_api.cpp new file mode 100644 index 00000000..30d3bb84 --- /dev/null +++ b/core/module/module_api.cpp @@ -0,0 +1,226 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +#include "../../kernel.h" +#include "../../Fex.hpp" +#include "api.hpp" + +// show debug messages +// #define DEBUG_MODULE_API 1 + +#ifdef DEBUG_MODULE_API +#define modbg(m, ...) debug(m, ##__VA_ARGS__) +#else +#define modbg(m, ...) +#endif + +NewLock(ModuleDisplayPrintLock); + +void ModuleDebugPrint(char *String, __UINT64_TYPE__ modUniqueID) +{ + trace("[%ld] %s", modUniqueID, String); +} + +void ModuleDisplayPrint(char *String) +{ + SmartLock(ModuleDisplayPrintLock); + for (__UINT64_TYPE__ i = 0; i < strlen(String); i++) + Display->Print(String[i], 0, true); +} + +void *RequestPage(__UINT64_TYPE__ Size) +{ + void *ret = KernelAllocator.RequestPages(size_t(Size + 1)); + modbg("Allocated %ld pages (%#lx-%#lx)", + Size, (__UINT64_TYPE__)ret, + (__UINT64_TYPE__)ret + FROM_PAGES(Size)); + return ret; +} + +void FreePage(void *Page, __UINT64_TYPE__ Size) +{ + modbg("Freeing %ld pages (%#lx-%#lx)", + Size, (__UINT64_TYPE__)Page, + (__UINT64_TYPE__)Page + FROM_PAGES(Size)); + KernelAllocator.FreePages(Page, size_t(Size + 1)); +} + +void MapMemory(void *VirtualAddress, void *PhysicalAddress, __UINT64_TYPE__ Flags) +{ + SmartLock(ModuleDisplayPrintLock); + modbg("Mapping %#lx to %#lx with flags %#lx...", + (__UINT64_TYPE__)VirtualAddress, + (__UINT64_TYPE__)PhysicalAddress, Flags); + Memory::Virtual(KernelPageTable).Map(VirtualAddress, PhysicalAddress, Flags); +} + +void UnmapMemory(void *VirtualAddress) +{ + SmartLock(ModuleDisplayPrintLock); + modbg("Unmapping %#lx...", + (__UINT64_TYPE__)VirtualAddress); + Memory::Virtual(KernelPageTable).Unmap(VirtualAddress); +} + +void *Modulememcpy(void *Destination, void *Source, __UINT64_TYPE__ Size) +{ + SmartLock(ModuleDisplayPrintLock); + modbg("Copying %ld bytes from %#lx-%#lx to %#lx-%#lx...", Size, + (__UINT64_TYPE__)Source, (__UINT64_TYPE__)Source + Size, + (__UINT64_TYPE__)Destination, (__UINT64_TYPE__)Destination + Size); + return memcpy(Destination, Source, size_t(Size)); +} + +void *Modulememset(void *Destination, int Value, __UINT64_TYPE__ Size) +{ + SmartLock(ModuleDisplayPrintLock); + modbg("Setting value %#x at %#lx-%#lx (%ld bytes)...", Value, + (__UINT64_TYPE__)Destination, + (__UINT64_TYPE__)Destination + Size, Size); + return memset(Destination, Value, size_t(Size)); +} + +void ModuleNetSend(__UINT32_TYPE__ ModuleID, + __UINT8_TYPE__ *Data, + __UINT16_TYPE__ Size) +{ + // This is useless I guess... + if (NIManager) + NIManager->DrvSend(ModuleID, Data, Size); +} + +void ModuleNetReceive(__UINT32_TYPE__ ModuleID, + __UINT8_TYPE__ *Data, + __UINT16_TYPE__ Size) +{ + if (NIManager) + NIManager->DrvReceive(ModuleID, Data, Size); +} + +void ModuleAHCIDiskRead(__UINT32_TYPE__ ModuleID, + __UINT64_TYPE__ Sector, + __UINT8_TYPE__ *Data, + __UINT32_TYPE__ SectorCount, + __UINT8_TYPE__ Port) +{ + DumpData("ModuleDiskRead", Data, SectorCount * 512); + UNUSED(ModuleID); + UNUSED(Sector); + UNUSED(Port); +} + +void ModuleAHCIDiskWrite(__UINT32_TYPE__ ModuleID, + __UINT64_TYPE__ Sector, + __UINT8_TYPE__ *Data, + __UINT32_TYPE__ SectorCount, + __UINT8_TYPE__ Port) +{ + DumpData("ModuleDiskWrite", + Data, SectorCount * 512); + UNUSED(ModuleID); + UNUSED(Sector); + UNUSED(Port); +} + +char *ModulePCIGetDeviceName(__UINT32_TYPE__ VendorID, + __UINT32_TYPE__ DeviceID) +{ + UNUSED(VendorID); + UNUSED(DeviceID); + return (char *)"Unknown"; +} + +__UINT32_TYPE__ ModuleGetWidth() +{ + return Display->GetBuffer(0)->Width; +} + +__UINT32_TYPE__ ModuleGetHeight() +{ + return Display->GetBuffer(0)->Height; +} + +void ModuleSleep(__UINT64_TYPE__ Milliseconds) +{ + SmartLock(ModuleDisplayPrintLock); + modbg("Sleeping for %ld milliseconds...", Milliseconds); + if (TaskManager) + TaskManager->Sleep(Milliseconds); + else + TimeManager->Sleep(size_t(Milliseconds), + Time::Units::Milliseconds); +} + +int Modulesprintf(char *Buffer, const char *Format, ...) +{ + va_list args; + va_start(args, Format); + int ret = vsprintf(Buffer, Format, args); + va_end(args); + return ret; +} + +KernelAPI KernelAPITemplate = { + .Version = { + .Major = 0, + .Minor = 0, + .Patch = 1}, + .Info = { + .Offset = 0, + .modUniqueID = 0, + .KernelDebug = false, + }, + .Memory = { + .PageSize = PAGE_SIZE, + .RequestPage = RequestPage, + .FreePage = FreePage, + .Map = MapMemory, + .Unmap = UnmapMemory, + }, + .PCI = { + .GetDeviceName = ModulePCIGetDeviceName, + }, + .Util = { + .DebugPrint = ModuleDebugPrint, + .DisplayPrint = ModuleDisplayPrint, + .memcpy = Modulememcpy, + .memset = Modulememset, + .Sleep = ModuleSleep, + .sprintf = Modulesprintf, + }, + .Command = { + .Network = { + .SendPacket = ModuleNetSend, + .ReceivePacket = ModuleNetReceive, + }, + .Disk = { + .AHCI = { + .ReadSector = ModuleAHCIDiskRead, + .WriteSector = ModuleAHCIDiskWrite, + }, + }, + }, + .Display = { + .GetWidth = ModuleGetWidth, + .GetHeight = ModuleGetHeight, + }, +}; diff --git a/core/module/module_binding/bind_input.cpp b/core/module/module_binding/bind_input.cpp new file mode 100644 index 00000000..f5bac93b --- /dev/null +++ b/core/module/module_binding/bind_input.cpp @@ -0,0 +1,42 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../api.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "../../../kernel.h" +#include "../../../mapi.hpp" +#include "../../../Fex.hpp" + +namespace Module +{ + ModuleCode Module::ModuleLoadBindInput(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn) + { + stub; + UNUSED(ModuleAddress); + UNUSED(Size); + UNUSED(IsBuiltIn); + return ModuleCode::NOT_IMPLEMENTED; + } +} diff --git a/core/module/module_binding/bind_interrupt.cpp b/core/module/module_binding/bind_interrupt.cpp new file mode 100644 index 00000000..d2d49a6d --- /dev/null +++ b/core/module/module_binding/bind_interrupt.cpp @@ -0,0 +1,118 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../api.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "../../../kernel.h" +#include "../../../mapi.hpp" +#include "../../../Fex.hpp" + +namespace Module +{ + ModuleCode Module::ModuleLoadBindInterrupt(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn) + { + Memory::VirtualMemoryArea *vma = new Memory::VirtualMemoryArea(nullptr); + + BuiltInModuleInfo *bidi = (BuiltInModuleInfo *)ModuleAddress; + Fex *fex = nullptr; + if (!IsBuiltIn) + { + fex = (Fex *)vma->RequestPages(TO_PAGES(Size + 1)); + memcpy(fex, (void *)ModuleAddress, Size); + debug("Module allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); + } + else + fex = (Fex *)bidi->EntryPoint; + ModuleCode ret = CallModuleEntryPoint(fex, IsBuiltIn); + if (ret != ModuleCode::OK) + { + delete vma; + return ret; + } + + if (IsBuiltIn) + fex = 0x0; /* Addresses are absolute if built-in. */ + + FexExtended *fexE = IsBuiltIn ? (FexExtended *)bidi->ExtendedHeader : (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + debug("Starting driver %s", fexE->Module.Name); + + switch (fexE->Module.Type) + { + case FexModuleType::FexModuleType_Generic: + case FexModuleType::FexModuleType_Display: + case FexModuleType::FexModuleType_Network: + case FexModuleType::FexModuleType_Storage: + case FexModuleType::FexModuleType_FileSystem: + case FexModuleType::FexModuleType_Input: + case FexModuleType::FexModuleType_Audio: + { + FexExtended *DriverExtendedHeader = (FexExtended *)vma->RequestPages(TO_PAGES(sizeof(FexExtended) + 1)); + memcpy(DriverExtendedHeader, fexE, sizeof(FexExtended)); + + ModuleFile DrvFile = { + .Enabled = true, + .BuiltIn = IsBuiltIn, + .modUniqueID = this->modUIDs - 1, + .Address = (void *)fex, + .ExtendedHeaderAddress = (void *)DriverExtendedHeader, + .InterruptCallback = (void *)((uintptr_t)fex + (uintptr_t)fexE->Module.InterruptCallback), + .vma = vma, + }; + + if (fexE->Module.InterruptCallback) + { + for (uint16_t i = 0; i < sizeof(fexE->Module.Bind.Interrupt.Vector) / sizeof(fexE->Module.Bind.Interrupt.Vector[0]); i++) + { + if (fexE->Module.Bind.Interrupt.Vector[i] == 0) + break; + DrvFile.InterruptHook[i] = new ModuleInterruptHook(fexE->Module.Bind.Interrupt.Vector[i], DrvFile); + } + } + + KernelCallback KCallback{}; + KCallback.RawPtr = nullptr; + KCallback.Reason = CallbackReason::ConfigurationReason; + ModuleCode CallbackRet = ((ModuleCode(*)(KernelCallback *))((uintptr_t)fexE->Module.Callback + (uintptr_t)fex))(&KCallback); + + if (CallbackRet != ModuleCode::OK) + { + error("Module %s returned error %d", fexE->Module.Name, CallbackRet); + delete vma; + return CallbackRet; + } + + Modules.push_back(DrvFile); + return ModuleCode::OK; + } + default: + { + warn("Unknown driver type: %d", fexE->Module.Type); + delete vma; + return ModuleCode::UNKNOWN_MODULE_TYPE; + } + } + } +} diff --git a/core/module/module_binding/bind_pci.cpp b/core/module/module_binding/bind_pci.cpp new file mode 100644 index 00000000..3427dd40 --- /dev/null +++ b/core/module/module_binding/bind_pci.cpp @@ -0,0 +1,145 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../api.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "../../../kernel.h" +#include "../../../mapi.hpp" +#include "../../../Fex.hpp" + +namespace Module +{ + ModuleCode Module::ModuleLoadBindPCI(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn) + { + FexExtended *DrvExtHdr = (FexExtended *)(ModuleAddress + EXTENDED_SECTION_ADDRESS); + if (IsBuiltIn) + DrvExtHdr = (FexExtended *)(((BuiltInModuleInfo *)ModuleAddress)->ExtendedHeader); + + uint16_t SizeOfVendorID = sizeof(DrvExtHdr->Module.Bind.PCI.VendorID) / + sizeof(DrvExtHdr->Module.Bind.PCI.VendorID[0]); + uint16_t SizeOfDeviceID = sizeof(DrvExtHdr->Module.Bind.PCI.DeviceID) / + sizeof(DrvExtHdr->Module.Bind.PCI.DeviceID[0]); + + for (uint16_t vID = 0; vID < SizeOfVendorID; vID++) + { + for (uint16_t dID = 0; dID < SizeOfDeviceID; dID++) + { + if (DrvExtHdr->Module.Bind.PCI.VendorID[vID] == 0 || + DrvExtHdr->Module.Bind.PCI.DeviceID[dID] == 0) + continue; + + std::vector devices = + PCIManager->FindPCIDevice(DrvExtHdr->Module.Bind.PCI.VendorID[vID], + DrvExtHdr->Module.Bind.PCI.DeviceID[dID]); + if (devices.size() == 0) + continue; + + foreach (auto Device in devices) + { + debug("[%ld] VendorID: %#x; DeviceID: %#x", + devices.size(), Device.Header->VendorID, + Device.Header->DeviceID); + + Memory::VirtualMemoryArea *vma = new Memory::VirtualMemoryArea(nullptr); + + BuiltInModuleInfo *bidi = (BuiltInModuleInfo *)ModuleAddress; + Fex *fex = nullptr; + if (!IsBuiltIn) + { + fex = (Fex *)vma->RequestPages(TO_PAGES(Size + 1)); + memcpy(fex, (void *)ModuleAddress, Size); + debug("Module allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); + } + else + fex = (Fex *)bidi->EntryPoint; + ModuleCode ret = CallModuleEntryPoint(fex, IsBuiltIn); + if (ret != ModuleCode::OK) + { + delete vma; + return ret; + } + + if (IsBuiltIn) + fex = 0x0; /* Addresses are absolute if built-in. */ + + FexExtended *fexE = IsBuiltIn ? (FexExtended *)bidi->ExtendedHeader : (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + debug("Starting driver %s", fexE->Module.Name); + + PCIManager->MapPCIAddresses(Device); + + switch (fexE->Module.Type) + { + case FexModuleType::FexModuleType_Generic: + case FexModuleType::FexModuleType_Display: + case FexModuleType::FexModuleType_Network: + case FexModuleType::FexModuleType_Storage: + case FexModuleType::FexModuleType_FileSystem: + case FexModuleType::FexModuleType_Input: + case FexModuleType::FexModuleType_Audio: + { + FexExtended *DriverExtendedHeader = (FexExtended *)vma->RequestPages(TO_PAGES(sizeof(FexExtended) + 1)); + memcpy(DriverExtendedHeader, fexE, sizeof(FexExtended)); + + ModuleFile DrvFile = { + .Enabled = true, + .BuiltIn = IsBuiltIn, + .modUniqueID = this->modUIDs - 1, + .Address = (void *)fex, + .ExtendedHeaderAddress = (void *)DriverExtendedHeader, + .InterruptCallback = (void *)((uintptr_t)fex + (uintptr_t)fexE->Module.InterruptCallback), + .vma = vma, + }; + + if (fexE->Module.InterruptCallback) + DrvFile.InterruptHook[0] = new ModuleInterruptHook(((int)((PCI::PCIHeader0 *)Device.Header)->InterruptLine), DrvFile); + + KernelCallback KCallback{}; + KCallback.RawPtr = Device.Header; + KCallback.Reason = CallbackReason::ConfigurationReason; + ModuleCode CallbackRet = ((ModuleCode(*)(KernelCallback *))((uintptr_t)fexE->Module.Callback + (uintptr_t)fex))(&KCallback); + + if (CallbackRet != ModuleCode::OK) + { + error("Module %s returned error %d", fexE->Module.Name, CallbackRet); + delete vma; + return CallbackRet; + } + + Modules.push_back(DrvFile); + return ModuleCode::OK; + } + default: + { + warn("Unknown driver type: %d", fexE->Module.Type); + delete vma; + return ModuleCode::UNKNOWN_MODULE_TYPE; + } + } + } + } + } + return ModuleCode::PCI_DEVICE_NOT_FOUND; + } +} diff --git a/core/module/module_binding/bind_process.cpp b/core/module/module_binding/bind_process.cpp new file mode 100644 index 00000000..f3469def --- /dev/null +++ b/core/module/module_binding/bind_process.cpp @@ -0,0 +1,42 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../api.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "../../../kernel.h" +#include "../../../mapi.hpp" +#include "../../../Fex.hpp" + +namespace Module +{ + ModuleCode Module::ModuleLoadBindProcess(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn) + { + stub; + UNUSED(ModuleAddress); + UNUSED(Size); + UNUSED(IsBuiltIn); + return ModuleCode::NOT_IMPLEMENTED; + } +} diff --git a/Core/PeripheralComponentInterconnect.cpp b/core/pci.cpp similarity index 88% rename from Core/PeripheralComponentInterconnect.cpp rename to core/pci.cpp index f1a342a4..1176059e 100644 --- a/Core/PeripheralComponentInterconnect.cpp +++ b/core/pci.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -784,22 +784,22 @@ namespace PCI } #endif - void PCI::MapPCIAddresses(PCIDeviceHeader *PCIDevice, Memory::PageTable *Table) + void PCI::MapPCIAddresses(PCIDevice Device, Memory::PageTable *Table) { - debug("Header Type: %d", PCIDevice->HeaderType); - switch (PCIDevice->HeaderType) + debug("Header Type: %d", Device.Header->HeaderType); + switch (Device.Header->HeaderType) { case 0: /* PCI Header 0 */ { uint32_t BAR[6] = {0}; size_t BARsSize[6] = {0}; - BAR[0] = ((PCIHeader0 *)PCIDevice)->BAR0; - BAR[1] = ((PCIHeader0 *)PCIDevice)->BAR1; - BAR[2] = ((PCIHeader0 *)PCIDevice)->BAR2; - BAR[3] = ((PCIHeader0 *)PCIDevice)->BAR3; - BAR[4] = ((PCIHeader0 *)PCIDevice)->BAR4; - BAR[5] = ((PCIHeader0 *)PCIDevice)->BAR5; + BAR[0] = ((PCIHeader0 *)Device.Header)->BAR0; + BAR[1] = ((PCIHeader0 *)Device.Header)->BAR1; + BAR[2] = ((PCIHeader0 *)Device.Header)->BAR2; + BAR[3] = ((PCIHeader0 *)Device.Header)->BAR3; + BAR[4] = ((PCIHeader0 *)Device.Header)->BAR4; + BAR[5] = ((PCIHeader0 *)Device.Header)->BAR5; debug("Type: %d; IOBase: %#lx; MemoryBase: %#lx", BAR[0] & 1, @@ -814,9 +814,9 @@ namespace PCI if ((BAR[i] & 1) == 0) /* Memory Base */ { - ((PCIHeader0 *)PCIDevice)->BAR0 = 0xFFFFFFFF; - size_t size = ((PCIHeader0 *)PCIDevice)->BAR0; - ((PCIHeader0 *)PCIDevice)->BAR0 = BAR[i]; + ((PCIHeader0 *)Device.Header)->BAR0 = 0xFFFFFFFF; + size_t size = ((PCIHeader0 *)Device.Header)->BAR0; + ((PCIHeader0 *)Device.Header)->BAR0 = BAR[i]; BARsSize[i] = size & (~15); BARsSize[i] = ~BARsSize[i] + 1; BARsSize[i] = BARsSize[i] & 0xFFFFFFFF; @@ -824,9 +824,9 @@ namespace PCI } else if ((BAR[i] & 1) == 1) /* I/O Base */ { - ((PCIHeader0 *)PCIDevice)->BAR1 = 0xFFFFFFFF; - size_t size = ((PCIHeader0 *)PCIDevice)->BAR1; - ((PCIHeader0 *)PCIDevice)->BAR1 = BAR[i]; + ((PCIHeader0 *)Device.Header)->BAR1 = 0xFFFFFFFF; + size_t size = ((PCIHeader0 *)Device.Header)->BAR1; + ((PCIHeader0 *)Device.Header)->BAR1 = BAR[i]; BARsSize[i] = size & (~3); BARsSize[i] = ~BARsSize[i] + 1; BARsSize[i] = BARsSize[i] & 0xFFFF; @@ -873,48 +873,60 @@ namespace PCI } default: { - error("Unknown header type %d", PCIDevice->HeaderType); + error("Unknown header type %d", Device.Header->HeaderType); return; } } } - void PCI::EnumerateFunction(uint64_t DeviceAddress, uintptr_t Function) + void PCI::EnumerateFunction(uint64_t DeviceAddress, uint32_t Function, PCIDevice dev) { + dev.Function = Function; + uintptr_t Offset = Function << 12; uint64_t FunctionAddress = DeviceAddress + Offset; Memory::Virtual(KernelPageTable).Map((void *)FunctionAddress, (void *)FunctionAddress, Memory::PTFlag::RW); PCIDeviceHeader *PCIDeviceHdr = (PCIDeviceHeader *)FunctionAddress; + dev.Header = PCIDeviceHdr; + if (PCIDeviceHdr->DeviceID == 0) return; if (PCIDeviceHdr->DeviceID == 0xFFFF) return; - Devices.push_back(PCIDeviceHdr); + + Devices.push_back(dev); #ifdef DEBUG e(PCIDeviceHdr); #endif } - void PCI::EnumerateDevice(uint64_t BusAddress, uintptr_t Device) + void PCI::EnumerateDevice(uint64_t BusAddress, uint32_t Device, PCIDevice dev) { + dev.Device = Device; + uintptr_t Offset = Device << 15; uint64_t DeviceAddress = BusAddress + Offset; Memory::Virtual(KernelPageTable).Map((void *)DeviceAddress, (void *)DeviceAddress, Memory::PTFlag::RW); PCIDeviceHeader *PCIDeviceHdr = (PCIDeviceHeader *)DeviceAddress; + if (PCIDeviceHdr->DeviceID == 0) return; if (PCIDeviceHdr->DeviceID == 0xFFFF) return; - for (uintptr_t Function = 0; Function < 8; Function++) - EnumerateFunction(DeviceAddress, Function); + + for (uint32_t Function = 0; Function < 8; Function++) + EnumerateFunction(DeviceAddress, Function, dev); } - void PCI::EnumerateBus(uint64_t BaseAddress, uintptr_t Bus) + void PCI::EnumerateBus(uint64_t BaseAddress, uint32_t Bus, PCIDevice dev) { + dev.Bus = Bus; + uintptr_t Offset = Bus << 20; uint64_t BusAddress = BaseAddress + Offset; Memory::Virtual(KernelPageTable).Map((void *)BusAddress, (void *)BusAddress, Memory::PTFlag::RW); PCIDeviceHeader *PCIDeviceHdr = (PCIDeviceHeader *)BusAddress; + if (Bus != 0) // TODO: VirtualBox workaround (UNTESTED ON REAL HARDWARE!) { if (PCIDeviceHdr->DeviceID == 0) @@ -922,30 +934,43 @@ namespace PCI if (PCIDeviceHdr->DeviceID == 0xFFFF) return; } + debug("PCI Bus DeviceID:%#x VendorID:%#x BIST:%#x Cache:%#x Class:%#x Cmd:%#x HdrType:%#x LatencyTimer:%#x ProgIF:%#x RevID:%#x Status:%#x SubClass:%#x ", PCIDeviceHdr->DeviceID, PCIDeviceHdr->VendorID, PCIDeviceHdr->BIST, PCIDeviceHdr->CacheLineSize, PCIDeviceHdr->Class, PCIDeviceHdr->Command, PCIDeviceHdr->HeaderType, PCIDeviceHdr->LatencyTimer, PCIDeviceHdr->ProgIF, PCIDeviceHdr->RevisionID, PCIDeviceHdr->Status, PCIDeviceHdr->Subclass); - for (uintptr_t Device = 0; Device < 32; Device++) - EnumerateDevice(BusAddress, Device); + + for (uint32_t Device = 0; Device < 32; Device++) + EnumerateDevice(BusAddress, Device, dev); } - std::vector PCI::FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF) + std::vector PCI::FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF) { - std::vector DeviceFound; - for (auto var : Devices) - if (var->Class == Class && var->Subclass == Subclass && var->ProgIF == ProgIF) - DeviceFound.push_back(var); + std::vector DeviceFound; + foreach (auto dev in Devices) + { + if (dev.Header->Class == Class && + dev.Header->Subclass == Subclass && + dev.Header->ProgIF == ProgIF) + { + DeviceFound.push_back(dev); + } + } return DeviceFound; } - std::vector PCI::FindPCIDevice(int VendorID, int DeviceID) + std::vector PCI::FindPCIDevice(int VendorID, int DeviceID) { - std::vector DeviceFound; - for (auto var : Devices) - if (var->VendorID == VendorID && var->DeviceID == DeviceID) - DeviceFound.push_back(var); + std::vector DeviceFound; + foreach (auto dev in Devices) + { + if (dev.Header->VendorID == VendorID && + dev.Header->DeviceID == DeviceID) + { + DeviceFound.push_back(dev); + } + } return DeviceFound; } @@ -972,15 +997,16 @@ namespace PCI vmm.Map((void *)NewDeviceConfig->BaseAddress, (void *)NewDeviceConfig->BaseAddress, Memory::PTFlag::RW); debug("PCI Entry %d Address:%p BUS:%#x-%#x", t, NewDeviceConfig->BaseAddress, NewDeviceConfig->StartBus, NewDeviceConfig->EndBus); - for (uintptr_t Bus = NewDeviceConfig->StartBus; Bus < NewDeviceConfig->EndBus; Bus++) - EnumerateBus(NewDeviceConfig->BaseAddress, Bus); + + PCIDevice dev{}; + dev.Config = NewDeviceConfig; + for (uint32_t Bus = NewDeviceConfig->StartBus; Bus < NewDeviceConfig->EndBus; Bus++) + EnumerateBus(NewDeviceConfig->BaseAddress, Bus, dev); } #elif defined(aa64) error("PCI not implemented on aarch64"); #endif } - PCI::~PCI() - { - } + PCI::~PCI() {} } diff --git a/Core/Power.cpp b/core/power.cpp similarity index 68% rename from Core/Power.cpp rename to core/power.cpp index 45b10fc8..4f0c2f01 100644 --- a/Core/Power.cpp +++ b/core/power.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/Random.cpp b/core/random.cpp similarity index 83% rename from Core/Random.cpp rename to core/random.cpp index bd513084..a0df724d 100644 --- a/Core/Random.cpp +++ b/core/random.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/SystemManagementBIOS.cpp b/core/smbios.cpp similarity index 78% rename from Core/SystemManagementBIOS.cpp rename to core/smbios.cpp index 9d7159f7..a28bacf3 100644 --- a/Core/SystemManagementBIOS.cpp +++ b/core/smbios.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "smbios.hpp" diff --git a/Core/smbios.hpp b/core/smbios.hpp similarity index 94% rename from Core/smbios.hpp rename to core/smbios.hpp index c2f31cb7..92af5d39 100644 --- a/Core/smbios.hpp +++ b/core/smbios.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_SMBIOS_H__ diff --git a/Core/StackCheck.cpp b/core/stack_check.cpp similarity index 73% rename from Core/StackCheck.cpp rename to core/stack_check.cpp index ee73d99f..f3fce773 100644 --- a/Core/StackCheck.cpp +++ b/core/stack_check.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/Symbols.cpp b/core/symbols.cpp similarity index 81% rename from Core/Symbols.cpp rename to core/symbols.cpp index 4dd444b0..fa87d4bb 100644 --- a/Core/Symbols.cpp +++ b/core/symbols.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -54,7 +54,7 @@ namespace SymbolResolver __unused uint64_t Shndx, uintptr_t Sections) { - char *sections = reinterpret_cast(Sections); + char *sections = r_cst(char *, Sections); Elf_Sym *Symbols = nullptr; uint8_t *StringAddress = nullptr; @@ -119,12 +119,34 @@ namespace SymbolResolver trace("Symbol table loaded, %d entries (%ld KiB)", TotalEntries, TO_KiB(TotalEntries * sizeof(SymbolTable))); - Elf_Sym *sym = nullptr; - const char *name = nullptr; + Elf_Sym *sym; + const char *name; + Memory::Virtual vma = Memory::Virtual(); for (size_t i = 0, g = TotalEntries; i < g; i++) { sym = &Symbols[i]; + if (!vma.Check(sym)) + { + error("Symbol %d has invalid address %#lx!", + i, sym); + debug("Base: %#lx, Symbols[%d]: %#lx, Symbols[%d]: %#lx", + Symbols, + i - 1, &Symbols[i - 1], + i + 1, &Symbols[i + 1]); + continue; + } + name = (const char *)&StringAddress[Symbols[i].st_name]; + if (!vma.Check((void *)name)) + { + error("String %d has invalid address %#lx!", + i, name); + debug("st_name: %d, st_info: %d, st_other: %d, st_shndx: %d, st_value: %d, st_size: %d", + sym->st_name, sym->st_info, sym->st_other, + sym->st_shndx, sym->st_value, sym->st_size); + continue; + } + if (strlen(name) == 0) continue; SymbolTable tbl{}; diff --git a/Core/Time/HighPrecisionEventTimer.cpp b/core/time/hpet.cpp similarity index 78% rename from Core/Time/HighPrecisionEventTimer.cpp rename to core/time/hpet.cpp index bcca7e2a..5079fc82 100644 --- a/Core/Time/HighPrecisionEventTimer.cpp +++ b/core/time/hpet.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/Time/Time.cpp b/core/time/time.cpp similarity index 57% rename from Core/Time/Time.cpp rename to core/time/time.cpp index acb66fe9..1b7dc029 100644 --- a/Core/Time/Time.cpp +++ b/core/time/time.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -69,7 +69,9 @@ namespace Time result.Year = 1970; while (Days >= 365) { - if (result.Year % 4 == 0 && (result.Year % 100 != 0 || result.Year % 400 == 0)) + if (result.Year % 4 == 0 && + (result.Year % 100 != 0 || + result.Year % 400 == 0)) { if (Days >= 366) { @@ -86,20 +88,24 @@ namespace Time } } - int DaysInMonth[] = {31, result.Year % 4 == 0 ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int DaysInMonth[] = {31, + result.Year % 4 == 0 + ? 29 + : 28, + 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (result.Month = 0; result.Month < 12; result.Month++) { - if (Days < static_cast(DaysInMonth[result.Month])) + if (Days < s_cst(uint64_t, (DaysInMonth[result.Month]))) break; Days -= DaysInMonth[result.Month]; } result.Month++; - result.Day = static_cast(Days) + 1; - result.Hour = static_cast(Hours % 24); - result.Minute = static_cast(Minutes % 60); - result.Second = static_cast(Seconds % 60); - result.Counter = static_cast(Timestamp); + result.Day = s_cst(int, (Days) + 1); + result.Hour = s_cst(int, (Hours % 24)); + result.Minute = s_cst(int, (Minutes % 60)); + result.Second = s_cst(int, (Seconds % 60)); + result.Counter = s_cst(uint64_t, (Timestamp)); return result; } } diff --git a/Core/Time/Timer.cpp b/core/time/timer.cpp similarity index 84% rename from Core/Time/Timer.cpp rename to core/time/timer.cpp index b797052b..0e77986b 100644 --- a/Core/Time/Timer.cpp +++ b/core/time/timer.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/Time/TimeStampCounter.cpp b/core/time/tsc.cpp similarity index 64% rename from Core/Time/TimeStampCounter.cpp rename to core/time/tsc.cpp index 64ab4884..cf8ae06e 100644 --- a/Core/Time/TimeStampCounter.cpp +++ b/core/time/tsc.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Core/UniversalAsynchronousReceiverTransmitter.cpp b/core/uart.cpp similarity index 78% rename from Core/UniversalAsynchronousReceiverTransmitter.cpp rename to core/uart.cpp index cdbd6b78..3460b8fe 100644 --- a/Core/UniversalAsynchronousReceiverTransmitter.cpp +++ b/core/uart.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -20,7 +20,7 @@ #include #include -volatile bool serialports[8] = {false, false, false, false, false, false, false, false}; +bool serialports[8] = {false, false, false, false, false, false, false, false}; std::vector RegisteredEvents; #if defined(a86) @@ -60,6 +60,13 @@ namespace UniversalAsynchronousReceiverTransmitter if (Port == COMNULL) return; + uint8_t com = NoProfiler_inportb(Port); + if (com == 0xFF) + { + error("Serial port %#lx is not available.", Port); + return; + } + this->Port = Port; int PortNumber = 0; @@ -113,7 +120,7 @@ namespace UniversalAsynchronousReceiverTransmitter // { // static int once = 0; // if (!once++) - // warn("Serial port %#llx is faulty.", Port); + // warn("Serial port %#lx is faulty.", Port); // // serialports[Port] = false; // ignore for now // // return; // } @@ -121,6 +128,7 @@ namespace UniversalAsynchronousReceiverTransmitter // Set to normal operation mode. NoProfiler_outportb(s_cst(uint16_t, Port + 4), 0x0F); serialports[PortNumber] = true; + this->IsAvailable = true; #endif } @@ -128,6 +136,8 @@ namespace UniversalAsynchronousReceiverTransmitter SafeFunction NIF void UART::Write(uint8_t Char) { + if (!this->IsAvailable) + return; #if defined(a86) while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & SERIAL_BUFFER_EMPTY) == 0) ; @@ -140,6 +150,8 @@ namespace UniversalAsynchronousReceiverTransmitter SafeFunction NIF uint8_t UART::Read() { + if (!this->IsAvailable) + return 0; #if defined(a86) while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & 1) == 0) ; diff --git a/Core/UndefinedBehaviorSanitization.c b/core/ubsan.c similarity index 94% rename from Core/UndefinedBehaviorSanitization.c rename to core/ubsan.c index 5c5ad36c..34f6f358 100644 --- a/Core/UndefinedBehaviorSanitization.c +++ b/core/ubsan.c @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "ubsan.h" diff --git a/Core/ubsan.h b/core/ubsan.h similarity index 70% rename from Core/ubsan.h rename to core/ubsan.h index cb3e622a..00df0ee2 100644 --- a/Core/ubsan.h +++ b/core/ubsan.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_UBSAN_H__ diff --git a/Core/Video/Display.cpp b/core/video/display.cpp similarity index 91% rename from Core/Video/Display.cpp rename to core/video/display.cpp index 9656a0e9..070a14c9 100644 --- a/Core/Video/Display.cpp +++ b/core/video/display.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -20,9 +20,9 @@ #include #include -extern uintptr_t _binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_start; -extern uintptr_t _binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_end; -extern uintptr_t _binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_size; +extern uintptr_t _binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_start; +extern uintptr_t _binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_end; +extern uintptr_t _binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_size; NewLock(PrintLock); @@ -232,10 +232,7 @@ namespace Video this->Buffers[Index].DoNotScroll = Value; } -#if defined(a32) - __no_sanitize("undefined") -#endif - char Display::Print(char Char, int Index, bool WriteToUART) + __no_sanitize("undefined") char Display::Print(char Char, int Index, bool WriteToUART) { if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) return 0; @@ -417,7 +414,7 @@ namespace Video this->framebuffer = Info; if (LoadDefaultFont) { - this->CurrentFont = new Font(&_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, FontType::PCScreenFont2); + this->CurrentFont = new Font(&_binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, FontType::PCScreenFont2); #ifdef DEBUG FontInfo Info = this->CurrentFont->GetInfo(); debug("Font loaded: %dx%d %s", diff --git a/Core/Video/Font.cpp b/core/video/font.cpp similarity index 77% rename from Core/Video/Font.cpp rename to core/video/font.cpp index 4d8aab1c..66373f2c 100644 --- a/Core/Video/Font.cpp +++ b/core/video/font.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/ExecutionLayer/BinaryParse.cpp b/exec/binary_parse.cpp similarity index 62% rename from ExecutionLayer/BinaryParse.cpp rename to exec/binary_parse.cpp index 730f9f2d..02ad1e88 100644 --- a/ExecutionLayer/BinaryParse.cpp +++ b/exec/binary_parse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -36,9 +36,9 @@ namespace Execute Memory::SmartHeap sh = Memory::SmartHeap(1024); fread(fd, sh, 128); - Fex *FexHdr = (Fex *)sh.GetObject(); - Elf32_Ehdr *ELFHeader = (Elf32_Ehdr *)sh.GetObject(); - IMAGE_DOS_HEADER *MZHeader = (IMAGE_DOS_HEADER *)sh.GetObject(); + Fex *FexHdr = (Fex *)sh.Get(); + Elf32_Ehdr *ELFHeader = (Elf32_Ehdr *)sh.Get(); + IMAGE_DOS_HEADER *MZHeader = (IMAGE_DOS_HEADER *)sh.Get(); /* Check Fex header. */ if (FexHdr->Magic[0] == 'F' && @@ -53,10 +53,10 @@ namespace Execute Type = BinaryType::BinTypeFex; goto Success; } - else if (FexHdr->Type == FexFormatType_Driver) + else if (FexHdr->Type == FexFormatType_Module) { - fixme("Fex Driver is not supposed to be executed."); - /* TODO: Driver installation pop-up. */ + fixme("Fex Module is not supposed to be executed."); + /* TODO: Module installation pop-up. */ } } @@ -77,11 +77,11 @@ namespace Execute lseek(fd, MZHeader->e_lfanew, SEEK_SET); fread(fd, sh, 512); IMAGE_NT_HEADERS *PEHeader = - (IMAGE_NT_HEADERS *)(((char *)sh.GetObject()) + + (IMAGE_NT_HEADERS *)(((char *)sh.Get()) + MZHeader->e_lfanew); IMAGE_OS2_HEADER *NEHeader = - (IMAGE_OS2_HEADER *)(((char *)sh.GetObject()) + + (IMAGE_OS2_HEADER *)(((char *)sh.Get()) + MZHeader->e_lfanew); /* TODO: LE, EDOS */ diff --git a/ExecutionLayer/Elf/ElfLoader.cpp b/exec/elf/elf_loader.cpp similarity index 87% rename from ExecutionLayer/Elf/ElfLoader.cpp rename to exec/elf/elf_loader.cpp index b6a2aa03..65413d2b 100644 --- a/ExecutionLayer/Elf/ElfLoader.cpp +++ b/exec/elf/elf_loader.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -29,13 +29,13 @@ #include "../../Fex.hpp" using namespace Tasking; -using namespace VirtualFileSystem; +using namespace vfs; namespace Execute { void ELFObject::LoadPhdrs_x86_32(int fd, Elf64_Ehdr ELFHeader, - Memory::MemMgr *mm, + Memory::VirtualMemoryArea *vma, PCB *TargetProcess) { stub; @@ -46,7 +46,7 @@ namespace Execute void ELFObject::LoadPhdrs_x86_64(int fd, Elf64_Ehdr ELFHeader, - Memory::MemMgr *mm, + Memory::VirtualMemoryArea *vma, PCB *TargetProcess) { #if defined(a64) @@ -57,13 +57,13 @@ namespace Execute assert(size < 65536); assert(size < PAGE_SIZE); - ELFProgramHeaders = mm->RequestPages(TO_PAGES(size), true); + ELFProgramHeaders = vma->RequestPages(TO_PAGES(size), true); lseek(fd, ELFHeader.e_phoff, SEEK_SET); fread(fd, (uint8_t *)ELFProgramHeaders, size); #endif } - void ELFObject::GenerateAuxiliaryVector_x86_32(Memory::MemMgr *mm, + void ELFObject::GenerateAuxiliaryVector_x86_32(Memory::VirtualMemoryArea *vma, int fd, Elf32_Ehdr ELFHeader, uint32_t EntryPoint, @@ -71,20 +71,21 @@ namespace Execute { } - void ELFObject::GenerateAuxiliaryVector_x86_64(Memory::MemMgr *mm, + void ELFObject::GenerateAuxiliaryVector_x86_64(Memory::VirtualMemoryArea *vma, int fd, Elf64_Ehdr ELFHeader, uint64_t EntryPoint, uint64_t BaseAddress) { #if defined(a64) - char *aux_platform = (char *)mm->RequestPages(1, true); /* TODO: 4KiB is too much for this */ + char *aux_platform = (char *)vma->RequestPages(1, true); /* TODO: 4KiB is too much for this */ strcpy(aux_platform, "x86_64"); - std::string execfn = thisProcess->FileDescriptors->GetAbsolutePath(fd); - void *execfn_str = mm->RequestPages(TO_PAGES(execfn.size() + 1), true); - strcpy((char *)execfn_str, execfn.c_str()); - void *at_random = mm->RequestPages(1, true); + const char *execfn = thisProcess->FileDescriptors->GetAbsolutePath(fd); + void *execfn_str = vma->RequestPages(TO_PAGES(strlen(execfn) + 1), true); + strcpy((char *)execfn_str, execfn); + delete[] execfn; + void *at_random = vma->RequestPages(1, true); *(uint64_t *)at_random = Random::rand16(); Elfauxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}}); @@ -121,28 +122,26 @@ namespace Execute void ELFObject::LoadExec_x86_64(int fd, PCB *TargetProcess) { #if defined(a64) - std::string InterpreterPath; std::vector PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP); foreach (auto Interp in PhdrINTERP) { - Memory::SmartHeap sh = Memory::SmartHeap(256); + Memory::SmartHeap InterpreterPath = Memory::SmartHeap(256); lseek(fd, Interp.p_offset, SEEK_SET); - fread(fd, sh, 256); - InterpreterPath = sh; + fread(fd, InterpreterPath, 256); - int ifd = fopen(InterpreterPath.c_str(), "r"); + int ifd = fopen((const char *)InterpreterPath.Get(), "r"); if (ifd < 0) { warn("Failed to open interpreter file: %s", - InterpreterPath.c_str()); + (const char *)InterpreterPath.Get()); continue; } else { - if (GetBinaryType(InterpreterPath.c_str()) != BinTypeELF) + if (GetBinaryType((const char *)InterpreterPath.Get()) != BinTypeELF) { warn("Interpreter %s is not an ELF file", - InterpreterPath.c_str()); + (const char *)InterpreterPath.Get()); fclose(ifd); continue; } @@ -164,7 +163,9 @@ namespace Execute debug("Entry point is %#lx", EntryPoint); Memory::Virtual vmm = Memory::Virtual(TargetProcess->PageTable); - Memory::MemMgr *mm = TargetProcess->Memory; + Memory::VirtualMemoryArea *vma = TargetProcess->vma; + + LoadPhdrs_x86_64(fd, ELFHeader, vma, TargetProcess); /* Copy segments into memory */ { @@ -181,7 +182,7 @@ namespace Execute if (ProgramHeader.p_memsz == 0) continue; - void *pAddr = mm->RequestPages(TO_PAGES(ProgramHeader.p_memsz), true); + void *pAddr = vma->RequestPages(TO_PAGES(ProgramHeader.p_memsz), true); void *SegmentDestination = (void *)ProgramHeader.p_vaddr; vmm.Map(SegmentDestination, pAddr, @@ -231,11 +232,11 @@ namespace Execute Memory::SmartHeap sh = Memory::SmartHeap(statbuf.st_size); lseek(fd, 0, SEEK_SET); fread(fd, sh, statbuf.st_size); - TargetProcess->ELFSymbolTable->AppendSymbols(uintptr_t(sh.GetObject())); + TargetProcess->ELFSymbolTable->AppendSymbols(uintptr_t(sh.Get())); debug("Entry Point: %#lx", EntryPoint); - this->GenerateAuxiliaryVector_x86_64(mm, fd, ELFHeader, + this->GenerateAuxiliaryVector_x86_64(vma, fd, ELFHeader, EntryPoint, 0); this->ip = EntryPoint; @@ -253,28 +254,27 @@ namespace Execute void ELFObject::LoadDyn_x86_64(int fd, PCB *TargetProcess) { #if defined(a64) - std::string InterpreterPath; std::vector PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP); foreach (auto Interp in PhdrINTERP) { - Memory::SmartHeap sh = Memory::SmartHeap(256); + Memory::SmartHeap InterpreterPath = Memory::SmartHeap(256); lseek(fd, Interp.p_offset, SEEK_SET); - fread(fd, sh, 256); - InterpreterPath = sh; + fread(fd, InterpreterPath, 256); + InterpreterPath = InterpreterPath; - int ifd = fopen(InterpreterPath.c_str(), "r"); + int ifd = fopen((const char *)InterpreterPath.Get(), "r"); if (ifd < 0) { warn("Failed to open interpreter file: %s", - InterpreterPath.c_str()); + (const char *)InterpreterPath.Get()); continue; } else { - if (GetBinaryType(InterpreterPath.c_str()) != BinTypeELF) + if (GetBinaryType((const char *)InterpreterPath.Get()) != BinTypeELF) { warn("Interpreter %s is not an ELF file", - InterpreterPath.c_str()); + (const char *)InterpreterPath.Get()); fclose(ifd); continue; } @@ -296,10 +296,10 @@ namespace Execute debug("Entry point is %#lx", EntryPoint); Memory::Virtual vmm = Memory::Virtual(TargetProcess->PageTable); - Memory::MemMgr *mm = TargetProcess->Memory; + Memory::VirtualMemoryArea *vma = TargetProcess->vma; uintptr_t BaseAddress = 0; - LoadPhdrs_x86_64(fd, ELFHeader, mm, TargetProcess); + LoadPhdrs_x86_64(fd, ELFHeader, vma, TargetProcess); /* Copy segments into memory */ { @@ -326,7 +326,7 @@ namespace Execute /* TODO: Check if this is correct and/or it needs more complex calculations & allocations */ - void *SegmentsAddress = mm->RequestPages(TO_PAGES(SegmentsSize) + 1, true); + void *SegmentsAddress = vma->RequestPages(TO_PAGES(SegmentsSize) + 1, true); BaseAddress = (uintptr_t)SegmentsAddress; debug("BaseAddress: %#lx, End: %#lx (%#lx)", BaseAddress, BaseAddress + FROM_PAGES(TO_PAGES(SegmentsSize)), @@ -655,11 +655,11 @@ namespace Execute Memory::SmartHeap sh = Memory::SmartHeap(statbuf.st_size); lseek(fd, 0, SEEK_SET); fread(fd, sh, statbuf.st_size); - TargetProcess->ELFSymbolTable->AppendSymbols(uintptr_t(sh.GetObject()), BaseAddress); + TargetProcess->ELFSymbolTable->AppendSymbols(uintptr_t(sh.Get()), BaseAddress); debug("Entry Point: %#lx", EntryPoint); - this->GenerateAuxiliaryVector_x86_64(mm, fd, ELFHeader, + this->GenerateAuxiliaryVector_x86_64(vma, fd, ELFHeader, EntryPoint, BaseAddress); this->ip = EntryPoint; @@ -766,22 +766,22 @@ namespace Execute // ELFargv = new const char *[argc + 2]; size_t argv_size = TO_PAGES(argc + 2 * sizeof(char *)); - ELFargv = (const char **)TargetProcess->Memory->RequestPages(argv_size); + ELFargv = (const char **)TargetProcess->vma->RequestPages(argv_size); for (int i = 0; i < argc; i++) { size_t arg_size = TO_PAGES(strlen(argv[i]) + 1); - ELFargv[i] = (const char *)TargetProcess->Memory->RequestPages(arg_size); + ELFargv[i] = (const char *)TargetProcess->vma->RequestPages(arg_size); strcpy((char *)ELFargv[i], argv[i]); } ELFargv[argc] = nullptr; // ELFenvp = new const char *[envc + 1]; size_t envp_size = TO_PAGES(envc + 1 * sizeof(char *)); - ELFenvp = (const char **)TargetProcess->Memory->RequestPages(envp_size); + ELFenvp = (const char **)TargetProcess->vma->RequestPages(envp_size); for (int i = 0; i < envc; i++) { size_t env_size = TO_PAGES(strlen(envp[i]) + 1); - ELFenvp[i] = (const char *)TargetProcess->Memory->RequestPages(env_size); + ELFenvp[i] = (const char *)TargetProcess->vma->RequestPages(env_size); strcpy((char *)ELFenvp[i], envp[i]); } ELFenvp[envc] = nullptr; diff --git a/ExecutionLayer/Elf/ElfParse.cpp b/exec/elf/elf_parse.cpp similarity index 87% rename from ExecutionLayer/Elf/ElfParse.cpp rename to exec/elf/elf_parse.cpp index ea4c896a..a7cd7242 100644 --- a/ExecutionLayer/Elf/ElfParse.cpp +++ b/exec/elf/elf_parse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/ExecutionLayer/Elf/ElfRel.cpp b/exec/elf/elf_rel.cpp similarity index 82% rename from ExecutionLayer/Elf/ElfRel.cpp rename to exec/elf/elf_rel.cpp index dbfab361..fd6b35c2 100644 --- a/ExecutionLayer/Elf/ElfRel.cpp +++ b/exec/elf/elf_rel.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/ExecutionLayer/Elf/ParseFunctions/ELFGetDynamicTag.cpp b/exec/elf/parse/elf_get_dynamic_tag.cpp similarity index 61% rename from ExecutionLayer/Elf/ParseFunctions/ELFGetDynamicTag.cpp rename to exec/elf/parse/elf_get_dynamic_tag.cpp index e386b60d..202231de 100644 --- a/ExecutionLayer/Elf/ParseFunctions/ELFGetDynamicTag.cpp +++ b/exec/elf/parse/elf_get_dynamic_tag.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/ExecutionLayer/Elf/ParseFunctions/ELFGetSections.cpp b/exec/elf/parse/elf_get_sections.cpp similarity index 63% rename from ExecutionLayer/Elf/ParseFunctions/ELFGetSections.cpp rename to exec/elf/parse/elf_get_sections.cpp index b2027c5c..249d1560 100644 --- a/ExecutionLayer/Elf/ParseFunctions/ELFGetSections.cpp +++ b/exec/elf/parse/elf_get_sections.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/ExecutionLayer/Elf/ParseFunctions/ELFGetSymbolType.cpp b/exec/elf/parse/elf_get_symbol_type.cpp similarity index 55% rename from ExecutionLayer/Elf/ParseFunctions/ELFGetSymbolType.cpp rename to exec/elf/parse/elf_get_symbol_type.cpp index 071bd7ff..b3af84a3 100644 --- a/ExecutionLayer/Elf/ParseFunctions/ELFGetSymbolType.cpp +++ b/exec/elf/parse/elf_get_symbol_type.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/ExecutionLayer/Spawn.cpp b/exec/spawn.cpp similarity index 77% rename from ExecutionLayer/Spawn.cpp rename to exec/spawn.cpp index 4e9167d6..248e683f 100644 --- a/ExecutionLayer/Spawn.cpp +++ b/exec/spawn.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -129,7 +129,7 @@ namespace Execute KernelAllocator.FreePages(ElfFile, TO_PAGES(statbuf.st_size + 1)); - Process->SetWorkingDirectory(vfs->GetNodeFromPath(Path)->Parent); + Process->SetWorkingDirectory(fs->GetNodeFromPath(Path)->Parent); Process->Info.Compatibility = TaskCompatibility::Native; Process->Info.Architecture = TaskArchitecture::x64; @@ -142,6 +142,15 @@ namespace Execute return -ENOEXEC; } + /* FIXME: implement stdio fildes */ + vfs::FileDescriptorTable *fdt = Process->FileDescriptors; + // stdin + fdt->_open("/dev/tty", O_RDWR, 0666); + // stdout + fdt->_open("/dev/tty", O_RDWR, 0666); + // stderr + fdt->_open("/dev/tty", O_RDWR, 0666); + TCB *Thread = nullptr; { CriticalSection cs; @@ -150,7 +159,7 @@ namespace Execute obj->argv, obj->envp, obj->auxv, Arch, Compatibility); - Thread->SetCritical(true); + Thread->SetCritical(Critical); } fclose(fd); return Thread->ID; diff --git a/Files/tamsyn-font-1.11/LICENSE b/files/tamsyn-font-1.11/LICENSE similarity index 100% rename from Files/tamsyn-font-1.11/LICENSE rename to files/tamsyn-font-1.11/LICENSE diff --git a/Files/tamsyn-font-1.11/README b/files/tamsyn-font-1.11/README similarity index 100% rename from Files/tamsyn-font-1.11/README rename to files/tamsyn-font-1.11/README diff --git a/Files/tamsyn-font-1.11/Tamsyn10x20b.psf b/files/tamsyn-font-1.11/Tamsyn10x20b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn10x20b.psf rename to files/tamsyn-font-1.11/Tamsyn10x20b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn10x20r.psf b/files/tamsyn-font-1.11/Tamsyn10x20r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn10x20r.psf rename to files/tamsyn-font-1.11/Tamsyn10x20r.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn5x9b.psf b/files/tamsyn-font-1.11/Tamsyn5x9b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn5x9b.psf rename to files/tamsyn-font-1.11/Tamsyn5x9b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn5x9r.psf b/files/tamsyn-font-1.11/Tamsyn5x9r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn5x9r.psf rename to files/tamsyn-font-1.11/Tamsyn5x9r.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn6x12b.psf b/files/tamsyn-font-1.11/Tamsyn6x12b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn6x12b.psf rename to files/tamsyn-font-1.11/Tamsyn6x12b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn6x12r.psf b/files/tamsyn-font-1.11/Tamsyn6x12r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn6x12r.psf rename to files/tamsyn-font-1.11/Tamsyn6x12r.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn7x13b.psf b/files/tamsyn-font-1.11/Tamsyn7x13b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn7x13b.psf rename to files/tamsyn-font-1.11/Tamsyn7x13b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn7x13r.psf b/files/tamsyn-font-1.11/Tamsyn7x13r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn7x13r.psf rename to files/tamsyn-font-1.11/Tamsyn7x13r.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn7x14b.psf b/files/tamsyn-font-1.11/Tamsyn7x14b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn7x14b.psf rename to files/tamsyn-font-1.11/Tamsyn7x14b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn7x14r.psf b/files/tamsyn-font-1.11/Tamsyn7x14r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn7x14r.psf rename to files/tamsyn-font-1.11/Tamsyn7x14r.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn8x15b.psf b/files/tamsyn-font-1.11/Tamsyn8x15b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn8x15b.psf rename to files/tamsyn-font-1.11/Tamsyn8x15b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn8x15r.psf b/files/tamsyn-font-1.11/Tamsyn8x15r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn8x15r.psf rename to files/tamsyn-font-1.11/Tamsyn8x15r.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn8x16b.psf b/files/tamsyn-font-1.11/Tamsyn8x16b.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn8x16b.psf rename to files/tamsyn-font-1.11/Tamsyn8x16b.psf diff --git a/Files/tamsyn-font-1.11/Tamsyn8x16r.psf b/files/tamsyn-font-1.11/Tamsyn8x16r.psf similarity index 100% rename from Files/tamsyn-font-1.11/Tamsyn8x16r.psf rename to files/tamsyn-font-1.11/Tamsyn8x16r.psf diff --git a/include/abi.h b/include/abi.h index c046d755..a8741057 100644 --- a/include/abi.h +++ b/include/abi.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_ABI_H__ diff --git a/include/acpi.hpp b/include/acpi.hpp index 8f6f6179..6a28a435 100644 --- a/include/acpi.hpp +++ b/include/acpi.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_ACPI_H__ diff --git a/include/bitmap.hpp b/include/bitmap.hpp index d8f38b6f..68275e5d 100644 --- a/include/bitmap.hpp +++ b/include/bitmap.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_BITMAP_H__ diff --git a/include/boot/binfo.h b/include/boot/binfo.h index 28e28da0..251d6fc8 100644 --- a/include/boot/binfo.h +++ b/include/boot/binfo.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_BOOT_INFO_H__ @@ -42,7 +42,7 @@ enum FramebufferType #define MAX_FRAMEBUFFERS 16 #define MAX_MEMORY_ENTRIES 256 -#define MAX_MODULES 16 +#define MAX_MODULES 4 struct BootInfo { diff --git a/include/convert.h b/include/convert.h index 13c206e5..a37e19f6 100644 --- a/include/convert.h +++ b/include/convert.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include/cpu.hpp b/include/cpu.hpp index f724b35c..a6fed5c5 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_H__ diff --git a/include/cpu/membar.hpp b/include/cpu/membar.hpp index cf958607..03902859 100644 --- a/include/cpu/membar.hpp +++ b/include/cpu/membar.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_MEMBAR_H__ diff --git a/include/cpu/signatures.hpp b/include/cpu/signatures.hpp index 0c737e72..148a9f23 100644 --- a/include/cpu/signatures.hpp +++ b/include/cpu/signatures.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_SIGNATURES_H__ diff --git a/include/cpu/x86/cpuid_amd.hpp b/include/cpu/x86/cpuid_amd.hpp index 14ffaa4c..66293e7b 100644 --- a/include/cpu/x86/cpuid_amd.hpp +++ b/include/cpu/x86/cpuid_amd.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x86_CPUID_AMD_H__ diff --git a/include/cpu/x86/cpuid_intel.hpp b/include/cpu/x86/cpuid_intel.hpp index daab9643..597f9997 100644 --- a/include/cpu/x86/cpuid_intel.hpp +++ b/include/cpu/x86/cpuid_intel.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x86_CPUID_INTEL_H__ diff --git a/include/cpu/x86/exceptions.hpp b/include/cpu/x86/exceptions.hpp index 3d7e071c..793b01d5 100644 --- a/include/cpu/x86/exceptions.hpp +++ b/include/cpu/x86/exceptions.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x86_EXCEPTIONS_H__ diff --git a/include/cpu/x86/hypervisor.hpp b/include/cpu/x86/hypervisor.hpp index 83db73fe..ea44bead 100644 --- a/include/cpu/x86/hypervisor.hpp +++ b/include/cpu/x86/hypervisor.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x86_CPUID_HYPERVISOR_H__ diff --git a/include/cpu/x86/interrupts.hpp b/include/cpu/x86/interrupts.hpp index e46d83d4..5e6f90ef 100644 --- a/include/cpu/x86/interrupts.hpp +++ b/include/cpu/x86/interrupts.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x86_INTERRUPTS_H__ diff --git a/include/cpu/x86/x32/cr.hpp b/include/cpu/x86/x32/cr.hpp index 150ca63b..1cf42bab 100644 --- a/include/cpu/x86/x32/cr.hpp +++ b/include/cpu/x86/x32/cr.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x32_CR_H__ diff --git a/include/cpu/x86/x32/msr.hpp b/include/cpu/x86/x32/msr.hpp index 0b749e4e..174b7ad5 100644 --- a/include/cpu/x86/x32/msr.hpp +++ b/include/cpu/x86/x32/msr.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x32_MSR_H__ diff --git a/include/cpu/x86/x64/SegmentDescriptors.hpp b/include/cpu/x86/x64/SegmentDescriptors.hpp index eeb56b4e..ffcb45bd 100644 --- a/include/cpu/x86/x64/SegmentDescriptors.hpp +++ b/include/cpu/x86/x64/SegmentDescriptors.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_SEGMENT_DESCRIPTORS_H__ diff --git a/include/cpu/x86/x64/cr.hpp b/include/cpu/x86/x64/cr.hpp index 5a8fb45d..2f770c27 100644 --- a/include/cpu/x86/x64/cr.hpp +++ b/include/cpu/x86/x64/cr.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x64_CR_H__ diff --git a/include/cpu/x86/x64/msr.hpp b/include/cpu/x86/x64/msr.hpp index a078cc19..39501161 100644 --- a/include/cpu/x86/x64/msr.hpp +++ b/include/cpu/x86/x64/msr.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CPU_x64_MSR_H__ diff --git a/include/crc32.h b/include/crc32.h index 23d6c692..36f390ea 100644 --- a/include/crc32.h +++ b/include/crc32.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CRC32_H__ diff --git a/include/debug.h b/include/debug.h index 79e8096d..4ca0970d 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_DEBUGGER_H__ diff --git a/include/disk.hpp b/include/disk.hpp index c332d575..ab4e710f 100644 --- a/include/disk.hpp +++ b/include/disk.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_DISK_H__ @@ -111,6 +111,7 @@ namespace Disk size_t Read(size_t Offset, size_t Count, uint8_t *Buffer) { + fixme("Read from partition %s", Label); return 0; UNUSED(Offset); UNUSED(Count); @@ -119,6 +120,7 @@ namespace Disk size_t Write(size_t Offset, size_t Count, uint8_t *Buffer) { + fixme("Read from partition %s", Label); return 0; UNUSED(Offset); UNUSED(Count); @@ -136,12 +138,13 @@ namespace Disk uint8_t *Buffer = nullptr; PartitionTable Table; PartitionStyle Style = PartitionStyle::Unknown; - std::vector Partitions; + std::vector Partitions; bool MechanicalDisk = false; size_t UniqueIdentifier = 0xdeadbeef; size_t Read(size_t Offset, size_t Count, uint8_t *Buffer) { + fixme("Read from disk %s", Name); return 0; UNUSED(Offset); UNUSED(Count); @@ -150,6 +153,7 @@ namespace Disk size_t Write(size_t Offset, size_t Count, uint8_t *Buffer) { + fixme("Read from disk %s", Name); return 0; UNUSED(Offset); UNUSED(Count); @@ -168,10 +172,10 @@ namespace Disk unsigned char AvailablePorts = 0; int BytesPerSector = 0; - std::vector drives; + std::vector drives; public: - void FetchDisks(unsigned long DriverUID); + void FetchDisks(unsigned long modUniqueID); Manager(); ~Manager(); }; diff --git a/include/display.hpp b/include/display.hpp index 57d54e43..fb40c900 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_DISPLAY_H__ diff --git a/include/driver.hpp b/include/driver.hpp deleted file mode 100644 index 26bab125..00000000 --- a/include/driver.hpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#ifndef __FENNIX_KERNEL_DRIVER_H__ -#define __FENNIX_KERNEL_DRIVER_H__ - -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace Driver -{ - enum DriverCode - { - /* This must be the same as in DAPI.hpp DriverReturnCode */ - ERROR, - OK, - NOT_IMPLEMENTED, - NOT_FOUND, - NOT_READY, - NOT_AVAILABLE, - NOT_AUTHORIZED, - NOT_VALID, - NOT_ACCEPTED, - INVALID_PCI_BAR, - INVALID_KERNEL_API, - INVALID_MEMORY_ALLOCATION, - INVALID_DATA, - DEVICE_NOT_SUPPORTED, - SYSTEM_NOT_SUPPORTED, - KERNEL_API_VERSION_NOT_SUPPORTED, - - /* End of driver-only errors */ - - INVALID_FEX_HEADER, - INVALID_DRIVER_DATA, - NOT_DRIVER, - DRIVER_RETURNED_ERROR, - UNKNOWN_DRIVER_TYPE, - UNKNOWN_DRIVER_BIND_TYPE, - PCI_DEVICE_NOT_FOUND, - DRIVER_CONFLICT - }; - - class DriverInterruptHook; - struct DriverFile - { - bool Enabled = false; - bool BuiltIn = false; - unsigned int DriverUID = 0; - void *Address = nullptr; - void *ExtendedHeaderAddress = nullptr; - void *InterruptCallback = nullptr; - Memory::MemMgr *MemTrk = nullptr; - DriverInterruptHook *InterruptHook[16]{}; - - bool operator==(const DriverFile &Other) const - { - return DriverUID == Other.DriverUID; - } - }; - - struct BuiltInDriverInfo - { - int (*EntryPoint)(void *); - void *ExtendedHeader; - }; - - class DriverInterruptHook : public Interrupts::Handler - { - private: - NewLock(DriverInterruptLock); - - DriverFile Handle; - bool Enabled = true; - -#if defined(a64) - void OnInterruptReceived(CPU::x64::TrapFrame *Frame); -#elif defined(a32) - void OnInterruptReceived(CPU::x32::TrapFrame *Frame); -#elif defined(aa64) - void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame); -#endif - - public: - void Enable() { Enabled = true; } - void Disable() { Enabled = false; } - bool IsEnabled() { return Enabled; } - DriverInterruptHook(int Interrupt, DriverFile Handle); - virtual ~DriverInterruptHook() = default; - }; - - class Driver - { - private: - NewLock(DriverInitLock); - - std::vector Drivers; - unsigned int DriverUIDs = 0; - /* If BuiltIn is true, the "fex" is the entry point. */ - DriverCode CallDriverEntryPoint(void *fex, bool BuiltIn = false); - - public: - /** - * @brief Load and bind a driver to a PCI device. - * - * This function will search for a PCI device with the given VendorID and DeviceID. - * If the device is found, the driver will be loaded and bound to the device. - * - * @param DriverAddress The address of the driver. The file will be copied to a new location. - * @param Size The size of the driver. - * @param IsBuiltIn If the driver is built-in, the @param DriverAddress will be @see BuiltInDriverInfo and the @param Size will be ignored. - * @return DriverCode The result of the operation. - */ - DriverCode DriverLoadBindPCI(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn = false); - - /** - * @brief Load and bind a driver to an interrupt. - * - * This function will search for an interrupt with the given IRQ. - * If the interrupt is found, the driver will be loaded and bound to the interrupt. - * - * @param DriverAddress The address of the driver. The file will be copied to a new location. - * @param Size The size of the driver. - * @param IsBuiltIn If the driver is built-in, the @param DriverAddress will be @see BuiltInDriverInfo and the @param Size will be ignored. - * @return DriverCode The result of the operation. - */ - DriverCode DriverLoadBindInterrupt(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn = false); - - /** - * @brief Load and bind a driver to an input device. - * - * This function will attach the driver to the input device. - * - * @param DriverAddress The address of the driver. The file will be copied to a new location. - * @param Size The size of the driver. - * @param IsBuiltIn If the driver is built-in, the @param DriverAddress will be @see BuiltInDriverInfo and the @param Size will be ignored. - * @return DriverCode The result of the operation. - */ - DriverCode DriverLoadBindInput(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn = false); - - /** - * @brief Load and bind a driver to a process. - * - * This function will attach the driver to the process. - * - * @param DriverAddress The address of the driver. The file will be copied to a new location. - * @param Size The size of the driver. - * @param IsBuiltIn If the driver is built-in, the @param DriverAddress will be @see BuiltInDriverInfo and the @param Size will be ignored. - * @return DriverCode The result of the operation. - */ - DriverCode DriverLoadBindProcess(uintptr_t DriverAddress, size_t Size, bool IsBuiltIn = false); - - /** - * @brief Get the currently loaded drivers. - * - * This function returns a clone of the drivers vector. - * This means that the vector can be modified without affecting the drivers. - * - * @return std::vector A clone of the drivers vector. - */ - std::vector GetDrivers() { return Drivers; } - - /* Reserved by the kernel */ - void Panic(); - - /** - * @brief Unload all drivers. - * - * This function will unload all drivers. - */ - void UnloadAllDrivers(); - - /** - * @brief Unload a driver. - * - * This function will unload a driver with the given driver unique ID. - * It will free the memory and remove the driver from the drivers vector. - * - * @param DUID The driver unique ID. - * @return true If the driver was found and unloaded successfully, false otherwise. - */ - bool UnloadDriver(unsigned long DUID); - - /** - * @brief Send a callback to a driver. - * - * This function will send a callback to a driver with the given driver unique ID. - * This is used to communicate with drivers. - * - * @param DUID The driver unique ID. - * @param KCB The @see KernelCallback structure. - * @return int The result of the operation. - */ - int IOCB(unsigned long DUID, /* KernelCallback */ void *KCB); - - /** - * @brief Load a driver. - * @param DriverAddress The address of the driver file. - * @param Size The size of the driver file. - * @return DriverCode The result of the operation. - */ - DriverCode LoadDriver(uintptr_t DriverAddress, size_t Size); - - /* Reserved by the kernel */ - void LoadDrivers(); - - /* Reserved by the kernel */ - Driver(); - - /* Reserved by the kernel */ - ~Driver(); - }; -} - -#endif // !__FENNIX_KERNEL_DRIVER_H__ diff --git a/include/dumper.hpp b/include/dumper.hpp index 58a0e381..f10b654a 100644 --- a/include/dumper.hpp +++ b/include/dumper.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_LIB_DUMPER_H__ diff --git a/include/elf.h b/include/elf.h index abc5c27f..300fd4bd 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_ELF_H__ diff --git a/include/emmintrin.h b/include/emmintrin.h index 878aadff..6f3af051 100644 --- a/include/emmintrin.h +++ b/include/emmintrin.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_EMMINTRIN_H__ diff --git a/include/exec.hpp b/include/exec.hpp index e0475b13..5255ba8e 100644 --- a/include/exec.hpp +++ b/include/exec.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILE_EXECUTE_H__ @@ -70,21 +70,21 @@ namespace Execute void LoadPhdrs_x86_32(int fd, Elf64_Ehdr ELFHeader, - Memory::MemMgr *mm, + Memory::VirtualMemoryArea *vma, Tasking::PCB *TargetProcess); void LoadPhdrs_x86_64(int fd, Elf64_Ehdr ELFHeader, - Memory::MemMgr *mm, + Memory::VirtualMemoryArea *vma, Tasking::PCB *TargetProcess); - void GenerateAuxiliaryVector_x86_32(Memory::MemMgr *mm, + void GenerateAuxiliaryVector_x86_32(Memory::VirtualMemoryArea *vma, int fd, Elf32_Ehdr ELFHeader, uint32_t EntryPoint, uint32_t BaseAddress); - void GenerateAuxiliaryVector_x86_64(Memory::MemMgr *mm, + void GenerateAuxiliaryVector_x86_64(Memory::VirtualMemoryArea *vma, int fd, Elf64_Ehdr ELFHeader, uint64_t EntryPoint, diff --git a/include/filesystem.hpp b/include/filesystem.hpp index 976fbcee..902fff9b 100644 --- a/include/filesystem.hpp +++ b/include/filesystem.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILESYSTEM_H__ @@ -27,24 +27,34 @@ #include #include -#define FILENAME_LENGTH 256 -#define PATH_MAX 256 - #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 +/** Other users have execute permission. */ #define S_IXOTH 0001 +/** Other users have write permission. */ #define S_IWOTH 0002 +/** Other users have read permission. */ #define S_IROTH 0004 +/** Other users have read, write, and execute permissions. */ #define S_IRWXO 0007 +/** Group members have execute permission. */ #define S_IXGRP 0010 +/** Group members have write permission. */ #define S_IWGRP 0020 +/** Group members have read permission. */ #define S_IRGRP 0040 +/** Group members have read, write, and execute permissions. */ #define S_IRWXG 0070 +/** The file owner has execute permission. */ #define S_IXUSR 0100 +/** The file owner has write permission. */ #define S_IWUSR 0200 +/** The file owner has read permission. */ #define S_IRUSR 0400 +/** The file owner has read, write, + * and execute permissions. */ #define S_IRWXU 0700 #define O_RDONLY 00 @@ -66,13 +76,13 @@ #define S_IFMT 0170000 -#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) -#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR) -#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK) -#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) -#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO) -#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK) -#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) struct stat { @@ -140,30 +150,11 @@ static inline int ConvertFileFlags(const char *Mode) return Flags; } -namespace VirtualFileSystem +namespace vfs { - struct Node; - - typedef std::size_t (*OperationRead)(Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset); - typedef std::size_t (*OperationWrite)(Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset); - typedef void (*OperationCreate)(Node *node, char *Name, uint16_t NameLength, off_t &RefOffset); - typedef void (*OperationMkdir)(Node *node, char *Name, uint16_t NameLength, off_t &RefOffset); - typedef std::size_t (*OperationSeek)(Node *node, std::size_t Offset, int Whence, off_t &RefOffset); - -#define ReadFSFunction(name) \ - std::size_t name(VirtualFileSystem::Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset) -#define WriteFSFunction(name) \ - std::size_t name(VirtualFileSystem::Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset) -#define CreateFSFunction(name) \ - void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength, off_t &RefOffset) -#define MkdirFSFunction(name) \ - void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength, off_t &RefOffset) -#define SeekFSFunction(name) \ - off_t name(VirtualFileSystem::Node *node, off_t Offset, uint8_t Whence, off_t &RefOffset) - - enum NodeFlags + enum NodeType : mode_t { - NODE_FLAG_ERROR = 0x0, + NODE_TYPE_NONE = 0x0, FILE = S_IFREG, DIRECTORY = S_IFDIR, CHARDEVICE = S_IFCHR, @@ -173,123 +164,105 @@ namespace VirtualFileSystem MOUNTPOINT = S_IFDIR }; - struct FileSystemOperations - { - /** - * Name of the filesystem operations - * - * @note Mandatory - */ - char Name[FILENAME_LENGTH]; - - /** - * Pointer to the read function - * - * @note Mandatory - */ - OperationRead Read = nullptr; - - /** - * Pointer to the write function - * - * @note Mandatory - */ - OperationWrite Write = nullptr; - - /** - * Pointer to the create function - * - * @note Optional - */ - OperationCreate Create = nullptr; - - /** - * Pointer to the mkdir function - * - * @note Optional - */ - OperationMkdir MakeDirectory = nullptr; - - /** - * Pointer to the seek function - * - * @note Optional - */ - OperationSeek Seek = nullptr; - }; - -#define RefNode VirtualFileSystem::ReferenceNode - - class ReferenceNode - { - private: - std::atomic_int64_t Offset = 0; - off_t FileSize = 0; - NewLock(RefNodeLock); - Node *node; - RefNode *SymlinkTo; - - public: - decltype(FileSize) &Length = FileSize; - Node *GetNode() const { return node; } - std::string AbsolutePath; - - size_t Read(uint8_t *Buffer, size_t Size); - size_t Write(uint8_t *Buffer, size_t Size); - off_t Seek(off_t Offset, int Whence); - - ReferenceNode(Node *node); - ~ReferenceNode(); - - friend class Virtual; - friend class FileDescriptorTable; - }; - + class RefNode; class Node { private: NewLock(NodeLock); public: - class Virtual *FileSystem = nullptr; - ino_t IndexNode = 0; - const char *Name; - const char *Symlink; - Node *SymlinkTarget = nullptr; - mode_t Mode = 0; - NodeFlags Flags = NodeFlags::NODE_FLAG_ERROR; - uid_t UserIdentifier = 0; - gid_t GroupIdentifier = 0; - uintptr_t Address = 0; - off_t Length = 0; + virtual int open(int Flags, mode_t Mode); + virtual int close(); + virtual size_t read(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual size_t write(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual int ioctl(unsigned long Request, + void *Argp); + virtual ~Node(); + + class Virtual *vFS = nullptr; Node *Parent = nullptr; - FileSystemOperations *Operator = nullptr; - /* For root node: - 0 - root "/" - 1 - etc - ... - */ + const char *Name; + const char *FullPath; + NodeType Type; + ino_t IndexNode; + + const char *Symlink; + Node *SymlinkTarget; + + mode_t Mode; + uid_t UserIdentifier; + gid_t GroupIdentifier; + + dev_t DeviceMajor; + dev_t DeviceMinor; + + time_t AccessTime; + time_t ModifyTime; + time_t ChangeTime; + + off_t Size; std::vector Children; - /** - * References to this node (open files, etc..) - */ - std::vector References; + std::vector References; + RefNode *CreateReference(); + void RemoveReference(RefNode *Reference); /** - * Create a new reference to this node - * @return Pointer to the new reference + * Delete all children of this node + * + * @note The function will self-delete + * if there are no errors. */ - ReferenceNode *CreateReference(); + int Delete(bool Recursive = false); /** - * Remove a reference to this node - * @param Reference Pointer to the reference to remove + * Create a new node + * + * @param Parent The parent node + * @param Name The name of the node + * @param Type The type of the node + * @param NoParent If true, the @param Parent will + * be used as a hint for the parent node, but it + * won't be set as the parent node. + * @param fs The virtual filesystem (only if + * NoParent is set) + * @param Err If not nullptr, the function will + * write the error code to the given address. */ - void RemoveReference(ReferenceNode *Reference); + Node(Node *Parent, + const char *Name, + NodeType Type, + bool NoParent = false, + Virtual *fs = nullptr, + int *Err = nullptr); + }; - Node() {} - ~Node() {} + class RefNode + { + private: + std::atomic_int64_t FileOffset = 0; + off_t FileSize = 0; + Node *n; + RefNode *SymlinkTo; + + public: + decltype(FileSize) &Size = FileSize; + decltype(n) &node = n; + + size_t read(uint8_t *Buffer, size_t Size); + size_t write(uint8_t *Buffer, size_t Size); + off_t seek(off_t Offset, int Whence); + int ioctl(unsigned long Request, void *Argp); + + RefNode(Node *node); + ~RefNode(); + + friend class Virtual; + friend class FileDescriptorTable; }; class Virtual @@ -298,73 +271,43 @@ namespace VirtualFileSystem Node *FileSystemRoot = nullptr; NewLock(VirtualLock); - /** - * @note This function is NOT thread safe - */ - Node *AddNewChild(const char *Name, Node *Parent); - - /** - * @note This function is NOT thread safe - */ - Node *GetChild(const char *Name, Node *Parent); - - /** - * @note This function is NOT thread safe - */ - int RemoveChild(const char *Name, Node *Parent); - - /** - * @note This function is NOT thread safe - */ Node *GetParent(const char *Path, Node *Parent); - - /** - * @note This function is NOT thread safe - */ + /** @note This function is NOT thread safe */ Node *GetNodeFromPath_Unsafe(const char *Path, Node *Parent = nullptr); public: - std::string GetPathFromNode(Node *node); + Node *nRoot = nullptr; Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr); bool PathIsRelative(const char *Path); Node *GetRootNode() { return FileSystemRoot; } - std::string NormalizePath(const char *Path, Node *Parent = nullptr); + const char *NormalizePath(const char *Path, Node *Parent = nullptr); bool PathExists(const char *Path, Node *Parent = nullptr); - Node *CreateRoot(const char *RootName, FileSystemOperations *Operator); - Node *Create(const char *Path, NodeFlags Flag, Node *Parent = nullptr); + + Node *Create(const char *Path, NodeType Type, Node *Parent = nullptr); int Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr); int Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr); - Node *Mount(const char *Path, FileSystemOperations *Operator); - int Unmount(Node *File); - /** * Open a file * @param Path The path to the file, relative or absolute. The buffer shouldn't be modified while the function is running. * @param Parent Pointer to the parent node, if nullptr, the root node will be used. - * @return A pointer to the VirtualFileSystem::ReferenceNode, or nullptr if the file doesn't exist. + * @return A pointer to the vfs::ReferenceNode, or nullptr if the file doesn't exist. */ RefNode *Open(const char *Path, Node *Parent = nullptr); Virtual(); ~Virtual(); + + friend class Node; }; class FileDescriptorTable { public: - struct winsize - { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; - }; - struct Fildes { RefNode *Handle{}; @@ -384,7 +327,7 @@ namespace VirtualFileSystem private: std::vector FileDescriptors; std::vector FildesDuplicates; - VirtualFileSystem::Node *fdDir = nullptr; + vfs::Node *fdDir = nullptr; Fildes GetFileDescriptor(int FileDescriptor); FileDescriptorTable::DupFildes GetDupFildes(int FileDescriptor); @@ -395,7 +338,7 @@ namespace VirtualFileSystem int GetFreeFileDescriptor(); public: - std::string GetAbsolutePath(int FileDescriptor); + const char *GetAbsolutePath(int FileDescriptor); std::vector &GetFileDescriptors() { return FileDescriptors; } int _open(const char *pathname, int flags, mode_t mode); diff --git a/include/filesystem/ext2.hpp b/include/filesystem/ext2.hpp index 24793cb2..dab23603 100644 --- a/include/filesystem/ext2.hpp +++ b/include/filesystem/ext2.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILESYSTEM_EXT2_H__ @@ -22,7 +22,7 @@ #include -namespace VirtualFileSystem +namespace vfs { class EXT2 { diff --git a/include/filesystem/fat.hpp b/include/filesystem/fat.hpp index 7781a403..30a083e1 100644 --- a/include/filesystem/fat.hpp +++ b/include/filesystem/fat.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILESYSTEM_FAT_H__ @@ -22,7 +22,7 @@ #include -namespace VirtualFileSystem +namespace vfs { class FAT { @@ -40,7 +40,7 @@ namespace VirtualFileSystem { /** @brief The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP. (The 3C value may be different.) The reason for this is to jump over the disk format information (the BPB and EBPB). Since the first sector of the disk is loaded into ram at location 0x0000:0x7c00 and executed, without this jump, the processor would attempt to execute data that isn't code. Even for non-bootable volumes, code matching this pattern (or using the E9 jump opcode) is required to be present by both Windows and OS X. To fulfil this requirement, an infinite loop can be placed here with the bytes EB FE 90. */ uint8_t JumpBoot[3]; - /** @brief OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read out the name of the version. The official FAT Specification from Microsoft says that this field is really meaningless and is ignored by MS FAT Drivers, however it does recommend the value "MSWIN4.1" as some 3rd party drivers supposedly check it and expect it to have that value. Older versions of dos also report MSDOS5.1, linux-formatted floppy will likely to carry "mkdosfs" here, and FreeDOS formatted disks have been observed to have "FRDOS5.1" here. If the string is less than 8 bytes, it is padded with spaces. */ + /** @brief OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read out the name of the version. The official FAT Specification from Microsoft says that this field is really meaningless and is ignored by MS FAT Modules, however it does recommend the value "MSWIN4.1" as some 3rd party drivers supposedly check it and expect it to have that value. Older versions of dos also report MSDOS5.1, linux-formatted floppy will likely to carry "mkdosfs" here, and FreeDOS formatted disks have been observed to have "FRDOS5.1" here. If the string is less than 8 bytes, it is padded with spaces. */ uint8_t OEM[8]; /** @brief The number of Bytes per sector (remember, all numbers are in the little-endian format). */ uint16_t BytesPerSector; diff --git a/include/filesystem/initrd.hpp b/include/filesystem/initrd.hpp index 994df1d3..9bfb3a93 100644 --- a/include/filesystem/initrd.hpp +++ b/include/filesystem/initrd.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILESYSTEM_INITRD_H__ @@ -22,7 +22,7 @@ #include -namespace VirtualFileSystem +namespace vfs { class Initrd { diff --git a/include/filesystem/ioctl.hpp b/include/filesystem/ioctl.hpp new file mode 100644 index 00000000..0024105a --- /dev/null +++ b/include/filesystem/ioctl.hpp @@ -0,0 +1,32 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_FILESYSTEM_IOCTL_H__ +#define __FENNIX_KERNEL_FILESYSTEM_IOCTL_H__ + +#include +#include + +struct winsize +{ + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#endif // !__FENNIX_KERNEL_FILESYSTEM_IOCTL_H__ diff --git a/include/filesystem/mounts.hpp b/include/filesystem/mounts.hpp index 94f2e5fa..9f663367 100644 --- a/include/filesystem/mounts.hpp +++ b/include/filesystem/mounts.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILESYSTEM_DEV_H__ @@ -22,9 +22,86 @@ #include -void Init_Null(VirtualFileSystem::Virtual *vfs_ctx); -void Init_Random(VirtualFileSystem::Virtual *vfs_ctx); -void Init_Teletype(VirtualFileSystem::Virtual *vfs_ctx); -void Init_Zero(VirtualFileSystem::Virtual *vfs_ctx); +namespace vfs +{ + class vfsRoot : public Node + { + public: + vfsRoot(const char *Name, Virtual *vfs_ctx); + ~vfsRoot() {} + }; + + class NullDevice : public Node + { + public: + virtual size_t read(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual size_t write(uint8_t *Buffer, + size_t Size, + off_t Offset); + + NullDevice(); + ~NullDevice(); + }; + + class RandomDevice : public Node + { + public: + virtual size_t read(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual size_t write(uint8_t *Buffer, + size_t Size, + off_t Offset); + + RandomDevice(); + ~RandomDevice(); + }; + + class ZeroDevice : public Node + { + public: + virtual size_t read(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual size_t write(uint8_t *Buffer, + size_t Size, + off_t Offset); + + ZeroDevice(); + ~ZeroDevice(); + }; + + class TTYDevice : public Node + { + public: + virtual size_t write(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual int ioctl(unsigned long Request, + void *Argp); + + TTYDevice(); + ~TTYDevice(); + }; + + class PTMXDevice : public Node + { + private: + Node *pts = nullptr; + + public: + virtual size_t read(uint8_t *Buffer, + size_t Size, + off_t Offset); + virtual size_t write(uint8_t *Buffer, + size_t Size, + off_t Offset); + + PTMXDevice(); + ~PTMXDevice(); + }; +} #endif // !__FENNIX_KERNEL_FILESYSTEM_DEV_H__ diff --git a/include/filesystem/ustar.hpp b/include/filesystem/ustar.hpp index 72ec83d5..ff12c369 100644 --- a/include/filesystem/ustar.hpp +++ b/include/filesystem/ustar.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_FILESYSTEM_USTAR_H__ @@ -22,69 +22,88 @@ #include -namespace VirtualFileSystem +namespace vfs { - class USTAR - { - enum FileType - { - REGULAR_FILE = '0', - HARDLINK = '1', - SYMLINK = '2', - CHARDEV = '3', - BLOCKDEV = '4', - DIRECTORY = '5', - FIFO = '6' - }; + class USTARNode : public Node + { + private: + uintptr_t Address; - struct FileHeader - { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char typeflag[1]; - char link[100]; - char signature[6]; - char version[2]; - char owner[32]; - char group[32]; - char dev_maj[8]; - char dev_min[8]; - char prefix[155]; - char pad[12]; - }; + public: + size_t read(uint8_t *Buffer, + size_t Size, + off_t Offset); - private: - uint32_t getsize(const char *s) - { - uint32_t ret = 0; - while (*s) - { - ret *= 8; - ret += *s - '0'; - s++; - } - return ret; - } + USTARNode(uintptr_t Address, + const char *Name, + NodeType Type, + Virtual *vfs_ctx); - int string2int(const char *str) - { - int res = 0; - for (int i = 0; str[i] != '\0'; ++i) - res = res * 10 + str[i] - '0'; - return res; - } + ~USTARNode(); + }; - public: - bool TestArchive(uintptr_t Address); - void ReadArchive(uintptr_t Address, Virtual *vfs_ctx); - USTAR(); - ~USTAR(); - }; + class USTAR + { + + enum FileType + { + REGULAR_FILE = '0', + HARDLINK = '1', + SYMLINK = '2', + CHARDEV = '3', + BLOCKDEV = '4', + DIRECTORY = '5', + FIFO = '6' + }; + + struct FileHeader + { + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag[1]; + char link[100]; + char signature[6]; + char version[2]; + char owner[32]; + char group[32]; + char dev_maj[8]; + char dev_min[8]; + char prefix[155]; + char pad[12]; + }; + + private: + uint32_t getsize(const char *s) + { + uint32_t ret = 0; + while (*s) + { + ret *= 8; + ret += *s - '0'; + s++; + } + return ret; + } + + int string2int(const char *str) + { + int res = 0; + for (int i = 0; str[i] != '\0'; ++i) + res = res * 10 + str[i] - '0'; + return res; + } + + public: + bool TestArchive(uintptr_t Address); + void ReadArchive(uintptr_t Address, Virtual *vfs_ctx); + USTAR(); + ~USTAR(); + }; } #endif // !__FENNIX_KERNEL_FILESYSTEM_USTAR_H__ diff --git a/include/hashmap.hpp b/include/hashmap.hpp index f1238609..e4f5c26d 100644 --- a/include/hashmap.hpp +++ b/include/hashmap.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include/intrin.hpp b/include/intrin.hpp index fc47ea70..4de9c434 100644 --- a/include/intrin.hpp +++ b/include/intrin.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_INTRIN_H__ diff --git a/include/ints.hpp b/include/ints.hpp index 99affe5b..d0be1686 100644 --- a/include/ints.hpp +++ b/include/ints.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_INTERRUPTS_H__ diff --git a/include/io.h b/include/io.h index e6bfc304..c5b90ab7 100644 --- a/include/io.h +++ b/include/io.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_IO_H__ diff --git a/include/ipc.hpp b/include/ipc.hpp index 2b6df6be..85ba19a6 100644 --- a/include/ipc.hpp +++ b/include/ipc.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_IPC_H__ @@ -56,7 +56,7 @@ namespace InterProcessCommunication struct IPCHandle { IPCID ID; - VirtualFileSystem::Node *Node; + vfs::Node *Node; void *Buffer; long Length; std::atomic_bool Listening; @@ -68,8 +68,8 @@ namespace InterProcessCommunication NewLock(IPCLock); IPCID NextID = 0; std::vector Handles; - Memory::MemMgr *mem; - VirtualFileSystem::Node *IPCNode; + Memory::VirtualMemoryArea *vma; + vfs::Node *IPCNode; void *Process; public: diff --git a/include/kconfig.hpp b/include/kconfig.hpp index 5a7a3f5f..9831106d 100644 --- a/include/kconfig.hpp +++ b/include/kconfig.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_KERNEL_CONFIG_H__ @@ -31,7 +31,7 @@ struct KernelConfig { Memory::MemoryAllocatorType AllocatorType; bool SchedulerType; - char DriverDirectory[256]; + char ModuleDirectory[256]; char InitPath[256]; bool UseLinuxSyscalls; bool InterruptsOnCrash; diff --git a/include/kshell.hpp b/include/kshell.hpp index 31ea0e45..997d2309 100644 --- a/include/kshell.hpp +++ b/include/kshell.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_KERNEL_SHELL_H__ diff --git a/include/lock.hpp b/include/lock.hpp index 710cc20f..65e5ac34 100644 --- a/include/lock.hpp +++ b/include/lock.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_LOCK_H__ diff --git a/include/md5.h b/include/md5.h index 382d47ab..9a8a8cc9 100644 --- a/include/md5.h +++ b/include/md5.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_MD5_H__ diff --git a/include/memory.hpp b/include/memory.hpp index c8abb766..751485fb 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_INTERNAL_MEMORY_H__ @@ -38,43 +38,6 @@ extern uintptr_t _kernel_data_start, _kernel_data_end; extern uintptr_t _kernel_rodata_start, _kernel_rodata_end; extern uintptr_t _kernel_bss_start, _kernel_bss_end; -// kilobyte -#define TO_KiB(d) ((d) / 1024) -// megabyte -#define TO_MiB(d) ((d) / 1024 / 1024) -// gigabyte -#define TO_GiB(d) ((d) / 1024 / 1024 / 1024) -// terabyte -#define TO_TiB(d) ((d) / 1024 / 1024 / 1024 / 1024) -// petabyte -#define TO_PiB(d) ((d) / 1024 / 1024 / 1024 / 1024 / 1024) -// exobyte -#define TO_EiB(d) ((d) / 1024 / 1024 / 1024 / 1024 / 1024 / 1024) - -#define PAGE_SIZE 0x1000 // 4KB -#define PAGE_SIZE_4K PAGE_SIZE // 4KB -#define PAGE_SIZE_2M 0x200000 // 2MB -#define PAGE_SIZE_4M 0x400000 // 4MB -#define PAGE_SIZE_1G 0x40000000 // 1GB - -#define STACK_SIZE 0x4000 // 16kb -#define USER_STACK_SIZE 0x2000 // 8kb - -// To pages -#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE) -// From pages -#define FROM_PAGES(d) ((d) * PAGE_SIZE) - -#if defined(a64) || defined(aa64) -#define KERNEL_VMA_OFFSET 0xFFFFFFFF80000000 -#define KERNEL_HEAP_BASE 0xFFFFFF0000000000 -#define USER_STACK_BASE 0xFFFFEFFFFFFF0000 -#elif defined(a32) -#define KERNEL_VMA_OFFSET 0xC0000000 -#define KERNEL_HEAP_BASE 0xA0000000 -#define USER_STACK_BASE 0xEFFFFFFF -#endif - namespace Memory { enum MemoryAllocatorType @@ -85,1089 +48,18 @@ namespace Memory XallocV2, liballoc11 }; - - /** - * @brief https://wiki.osdev.org/images/4/41/64-bit_page_tables1.png - * @brief https://wiki.osdev.org/images/6/6b/64-bit_page_tables2.png - */ - enum PTFlag - { - /** @brief Present */ - P = 1 << 0, - - /** @brief Read/Write */ - RW = 1 << 1, - - /** @brief User/Supervisor */ - US = 1 << 2, - - /** @brief Write-Through */ - PWT = 1 << 3, - - /** @brief Cache Disable */ - PCD = 1 << 4, - - /** @brief Accessed */ - A = 1 << 5, - - /** @brief Dirty */ - D = 1 << 6, - - /** @brief Page Size */ - PS = 1 << 7, - - /** @brief Global */ - G = 1 << 8, - - /** @brief Available 0 */ - AVL0 = 1 << 9, - - /** @brief Available 1 */ - AVL1 = 1 << 10, - - /** @brief Available 2 */ - AVL2 = 1 << 11, - - /** @brief Page Attribute Table */ - PAT = 1 << 12, - - /** @brief Available 3 */ - AVL3 = (uint64_t)1 << 52, - - /** @brief Available 4 */ - AVL4 = (uint64_t)1 << 53, - - /** @brief Available 5 */ - AVL5 = (uint64_t)1 << 54, - - /** @brief Available 6 */ - AVL6 = (uint64_t)1 << 55, - - /** @brief Available 7 */ - AVL7 = (uint64_t)1 << 56, - - /** @brief Available 8 */ - AVL8 = (uint64_t)1 << 57, - - /** @brief Available 9 */ - AVL9 = (uint64_t)1 << 58, - - /** @brief Protection Key 0 */ - PK0 = (uint64_t)1 << 59, - - /** @brief Protection Key 1 */ - PK1 = (uint64_t)1 << 60, - - /** @brief Protection Key 2 */ - PK2 = (uint64_t)1 << 61, - - /** @brief Protection Key 3 */ - PK3 = (uint64_t)1 << 62, - - /** @brief Execute Disable */ - XD = (uint64_t)1 << 63 - }; - - union __packed PageTableEntry - { - struct - { -#if defined(a64) - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Dirty : 1; // 6 - uintptr_t PageAttributeTable : 1; // 7 - uintptr_t Global : 1; // 8 - uintptr_t Available0 : 1; // 9 - uintptr_t Available1 : 1; // 10 - uintptr_t Available2 : 1; // 11 - uintptr_t Address : 40; // 12-51 - uintptr_t Available3 : 1; // 52 - uintptr_t Available4 : 1; // 53 - uintptr_t Available5 : 1; // 54 - uintptr_t Available6 : 1; // 55 - uintptr_t Available7 : 1; // 56 - uintptr_t Available8 : 1; // 57 - uintptr_t Available9 : 1; // 58 - uintptr_t ProtectionKey : 4; // 59-62 - uintptr_t ExecuteDisable : 1; // 63 -#elif defined(a32) - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Dirty : 1; // 6 - uintptr_t PageAttributeTable : 1; // 7 - uintptr_t Global : 1; // 8 - uintptr_t Available0 : 1; // 9 - uintptr_t Available1 : 1; // 10 - uintptr_t Available2 : 1; // 11 - uintptr_t Address : 20; // 12-31 -#elif defined(aa64) -#endif - }; - uintptr_t raw; - - /** @brief Set Address */ - void SetAddress(uintptr_t _Address) - { -#if defined(a64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#elif defined(a32) - _Address &= 0x000FFFFF; - this->raw &= 0xFFC00003; - this->raw |= (_Address << 12); -#elif defined(aa64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#endif - } - - /** @brief Get Address */ - uintptr_t GetAddress() - { -#if defined(a64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#elif defined(a32) - return ((uintptr_t)(this->raw & 0x003FFFFF000) >> 12); -#elif defined(aa64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#endif - } - }; - - struct __packed PageTableEntryPtr - { -#if defined(a64) - PageTableEntry Entries[512]; -#elif defined(a32) - PageTableEntry Entries[1024]; -#elif defined(aa64) -#endif - }; - - union __packed PageDirectoryEntry - { -#if defined(a64) - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Available0 : 1; // 6 - uintptr_t PageSize : 1; // 7 - uintptr_t Available1 : 4; // 8-11 - uintptr_t Address : 40; // 12-51 - uintptr_t Available2 : 11; // 52-62 - uintptr_t ExecuteDisable : 1; // 63 - }; - - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Dirty : 1; // 6 - uintptr_t PageSize : 1; // 7 - uintptr_t Global : 1; // 8 - uintptr_t Available0 : 1; // 9 - uintptr_t Available1 : 1; // 10 - uintptr_t Available2 : 1; // 11 - uintptr_t PageAttributeTable : 1; // 12 - uintptr_t Reserved0 : 8; // 13-20 - uintptr_t Address : 31; // 21-51 - uintptr_t Available3 : 1; // 52 - uintptr_t Available4 : 1; // 53 - uintptr_t Available5 : 1; // 54 - uintptr_t Available6 : 1; // 55 - uintptr_t Available7 : 1; // 56 - uintptr_t Available8 : 1; // 57 - uintptr_t Available9 : 1; // 58 - uintptr_t ProtectionKey : 4; // 59-62 - uintptr_t ExecuteDisable : 1; // 63 - } TwoMiB; -#elif defined(a32) - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Available0 : 1; // 6 - uintptr_t PageSize : 1; // 7 - uintptr_t Available1 : 4; // 8-11 - uintptr_t Address : 20; // 12-31 - }; - - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Dirty : 1; // 6 - uintptr_t PageSize : 1; // 7 - uintptr_t Global : 1; // 8 - uintptr_t Available0 : 1; // 9 - uintptr_t Available1 : 1; // 10 - uintptr_t Available2 : 1; // 11 - uintptr_t PageAttributeTable : 1; // 12 - uintptr_t Address0 : 8; // 13-20 - uintptr_t Reserved0 : 1; // 21 - uintptr_t Address1 : 10; // 22-31 - } FourMiB; -#elif defined(aa64) -#endif - uintptr_t raw; - - /** @brief Set PageTableEntryPtr address */ - void SetAddress(uintptr_t _Address) - { -#if defined(a64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#elif defined(a32) - _Address &= 0x000FFFFF; - this->raw &= 0xFFC00003; - this->raw |= (_Address << 12); -#elif defined(aa64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#endif - } - - /** @brief Get PageTableEntryPtr address */ - uintptr_t GetAddress() - { -#if defined(a64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#elif defined(a32) - return ((uintptr_t)(this->raw & 0x003FFFFF000) >> 12); -#elif defined(aa64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#endif - } - }; - - struct __packed PageDirectoryEntryPtr - { - PageDirectoryEntry Entries[512]; - }; - - union __packed PageDirectoryPointerTableEntry - { -#if defined(a64) - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Available0 : 1; // 6 - uintptr_t PageSize : 1; // 7 - uintptr_t Available1 : 4; // 8-11 - uintptr_t Address : 40; // 12-51 - uintptr_t Available2 : 11; // 52-62 - uintptr_t ExecuteDisable : 1; // 63 - }; - - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Dirty : 1; // 6 - uintptr_t PageSize : 1; // 7 - uintptr_t Global : 1; // 8 - uintptr_t Available0 : 1; // 9 - uintptr_t Available1 : 1; // 10 - uintptr_t Available2 : 1; // 11 - uintptr_t PageAttributeTable : 1; // 12 - uintptr_t Reserved0 : 17; // 13-29 - uintptr_t Address : 22; // 30-51 - uintptr_t Available3 : 1; // 52 - uintptr_t Available4 : 1; // 53 - uintptr_t Available5 : 1; // 54 - uintptr_t Available6 : 1; // 55 - uintptr_t Available7 : 1; // 56 - uintptr_t Available8 : 1; // 57 - uintptr_t Available9 : 1; // 58 - uintptr_t ProtectionKey : 4; // 59-62 - uintptr_t ExecuteDisable : 1; // 63 - } OneGiB; -#elif defined(aa64) -#endif - uintptr_t raw; - - /** @brief Set PageDirectoryEntryPtr address */ - void SetAddress(uintptr_t _Address) - { -#if defined(a64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#elif defined(aa64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#endif - } - - /** @brief Get PageDirectoryEntryPtr address */ - uintptr_t GetAddress() - { -#if defined(a64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#elif defined(a32) - return 0; -#elif defined(aa64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#endif - } - }; - - struct __packed PageDirectoryPointerTableEntryPtr - { - PageDirectoryPointerTableEntry Entries[512]; - }; - - union __packed PageMapLevel4 - { -#if defined(a64) - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Available0 : 1; // 6 - uintptr_t Reserved0 : 1; // 7 - uintptr_t Available1 : 4; // 8-11 - uintptr_t Address : 40; // 12-51 - uintptr_t Available2 : 11; // 52-62 - uintptr_t ExecuteDisable : 1; // 63 - }; -#elif defined(aa64) -#endif - uintptr_t raw; - - /** @brief Set PageDirectoryPointerTableEntryPtr address */ - void SetAddress(uintptr_t _Address) - { -#if defined(a64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#elif defined(aa64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#endif - } - - /** @brief Get PageDirectoryPointerTableEntryPtr address */ - uintptr_t GetAddress() - { -#if defined(a64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#elif defined(a32) - return 0; -#elif defined(aa64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#endif - } - }; - - struct __packed PageMapLevel4Ptr - { - PageMapLevel4 Entries[512]; - }; - - union __packed PageMapLevel5 - { -#if defined(a64) - struct - { - uintptr_t Present : 1; // 0 - uintptr_t ReadWrite : 1; // 1 - uintptr_t UserSupervisor : 1; // 2 - uintptr_t WriteThrough : 1; // 3 - uintptr_t CacheDisable : 1; // 4 - uintptr_t Accessed : 1; // 5 - uintptr_t Available0 : 1; // 6 - uintptr_t Reserved0 : 1; // 7 - uintptr_t Available1 : 4; // 8-11 - uintptr_t Address : 40; // 12-51 - uintptr_t Available2 : 11; // 52-62 - uintptr_t ExecuteDisable : 1; // 63 - }; -#elif defined(aa64) -#endif - uintptr_t raw; - - /** @brief Set PageMapLevel4Ptr address */ - void SetAddress(uintptr_t _Address) - { -#if defined(a64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#elif defined(aa64) - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); -#endif - } - - /** @brief Get PageMapLevel4Ptr address */ - uintptr_t GetAddress() - { -#if defined(a64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#elif defined(a32) - return 0; -#elif defined(aa64) - return (this->raw & 0x000FFFFFFFFFF000) >> 12; -#endif - } - }; - - class PageTable - { - public: -#if defined(a64) - PageMapLevel4 Entries[512]; -#elif defined(a32) - PageDirectoryEntry Entries[1024]; -#elif defined(aa64) -#endif - - /** - * @brief Update CR3 with this PageTable - */ - void Update(); - - /** - * @brief Fork this PageTable - * - * @return A new PageTable with the same content - */ - PageTable Fork(); - - template - T Get(T Address); - } __aligned(0x1000); - - class TempSwitchPT - { - private: - PageTable *Replace = nullptr; - PageTable *Restore = nullptr; - - public: - TempSwitchPT(PageTable *ReplaceWith, - PageTable *RestoreWith = nullptr) - : Replace(ReplaceWith) - { - extern PageTable *KernelPageTable; - - if (RestoreWith) - Restore = RestoreWith; - else - Restore = KernelPageTable; - - Replace->Update(); - } - - ~TempSwitchPT() { Restore->Update(); } - }; - - class Physical - { - private: - NewLock(MemoryLock); - - std::atomic_uint64_t TotalMemory = 0; - std::atomic_uint64_t FreeMemory = 0; - std::atomic_uint64_t ReservedMemory = 0; - std::atomic_uint64_t UsedMemory = 0; - uint64_t PageBitmapIndex = 0; - Bitmap PageBitmap; - - void ReserveEssentials(); - - public: - Bitmap GetPageBitmap() { return PageBitmap; } - - /** - * @brief Get Total Memory - * - * @return uint64_t - */ - uint64_t GetTotalMemory(); - - /** - * @brief Get Free Memory - * - * @return uint64_t - */ - uint64_t GetFreeMemory(); - - /** - * @brief Get Reserved Memory - * - * @return uint64_t - */ - uint64_t GetReservedMemory(); - - /** - * @brief Get Used Memory - * - * @return uint64_t - */ - uint64_t GetUsedMemory(); - - /** - * @brief Swap page - * - * @param Address Address of the page - * @return true if swap was successful - * @return false if swap was unsuccessful - */ - bool SwapPage(void *Address); - - /** - * @brief Swap pages - * - * @param Address Address of the pages - * @param PageCount Number of pages - * @return true if swap was successful - * @return false if swap was unsuccessful - */ - bool SwapPages(void *Address, size_t PageCount); - - /** - * @brief Unswap page - * - * @param Address Address of the page - * @return true if unswap was successful - * @return false if unswap was unsuccessful - */ - bool UnswapPage(void *Address); - - /** - * @brief Unswap pages - * - * @param Address Address of the pages - * @param PageCount Number of pages - * @return true if unswap was successful - * @return false if unswap was unsuccessful - */ - bool UnswapPages(void *Address, size_t PageCount); - - /** - * @brief Lock page - * - * @param Address Address of the page - */ - void LockPage(void *Address); - - /** - * @brief Lock pages - * - * @param Address Address of the pages - * @param PageCount Number of pages - */ - void LockPages(void *Address, size_t PageCount); - - void ReservePage(void *Address); - void ReservePages(void *Address, size_t PageCount); - void UnreservePage(void *Address); - void UnreservePages(void *Address, size_t PageCount); - - /** - * @brief Request page - * - * @return void* Allocated page address - */ - void *RequestPage(); - - /** - * @brief Request pages - * - * @param PageCount Number of pages - * @return void* Allocated pages address - */ - void *RequestPages(std::size_t Count); - - /** - * @brief Free page - * - * @param Address Address of the page - */ - void FreePage(void *Address); - - /** - * @brief Free pages - * - * @param Address Address of the pages - * @param PageCount Number of pages - */ - void FreePages(void *Address, size_t Count); - - /** @brief Do not use. */ - void Init(); - - /** @brief Do not use. */ - Physical(); - - /** @brief Do not use. */ - ~Physical(); - }; - - class Virtual - { - private: - NewLock(MemoryLock); - PageTable *Table = nullptr; - - public: - enum MapType - { - NoMapType, - FourKiB, - TwoMiB, - FourMiB, - OneGiB - }; - - class PageMapIndexer - { - public: -#if defined(a64) - uintptr_t PMLIndex = 0; - uintptr_t PDPTEIndex = 0; -#endif - uintptr_t PDEIndex = 0; - uintptr_t PTEIndex = 0; - PageMapIndexer(uintptr_t VirtualAddress); - }; - - /** - * @brief Check if page has the specified flag. - * - * @param VirtualAddress Virtual address of the page - * @param Flag Flag to check - * @param Type Type of the page. Check MapType enum. - * @return true if page has the specified flag. - * @return false if page is has the specified flag. - */ - bool Check(void *VirtualAddress, - PTFlag Flag = PTFlag::P, - MapType Type = MapType::FourKiB); - - /** - * @brief Get physical address of the page. - * @param VirtualAddress Virtual address of the page. - * @return Physical address of the page. - */ - void *GetPhysical(void *VirtualAddress); - - /** - * @brief Get map type of the page. - * @param VirtualAddress Virtual address of the page. - * @return Map type of the page. - */ - MapType GetMapType(void *VirtualAddress); - -#ifdef a64 - PageMapLevel5 *GetPML5(void *VirtualAddress, MapType Type = MapType::FourKiB); - PageMapLevel4 *GetPML4(void *VirtualAddress, MapType Type = MapType::FourKiB); - PageDirectoryPointerTableEntry *GetPDPTE(void *VirtualAddress, MapType Type = MapType::FourKiB); -#endif /* a64 */ - PageDirectoryEntry *GetPDE(void *VirtualAddress, MapType Type = MapType::FourKiB); - PageTableEntry *GetPTE(void *VirtualAddress, MapType Type = MapType::FourKiB); - - /** - * @brief Map page. - * - * @param VirtualAddress Virtual address of the page. - * @param PhysicalAddress Physical address of the page. - * @param Flags Flags of the page. Check PTFlag enum. - * @param Type Type of the page. Check MapType enum. - */ - void Map(void *VirtualAddress, - void *PhysicalAddress, - uint64_t Flag = PTFlag::P, - MapType Type = MapType::FourKiB); - - /** - * @brief Map multiple pages. - * - * @param VirtualAddress First virtual address of the page. - * @param PhysicalAddress First physical address of the page. - * @param Length Length to map. - * @param Flags Flags of the page. Check PTFlag enum. - * @param Type Type of the page. Check MapType enum. - */ - __always_inline inline void Map(void *VirtualAddress, - void *PhysicalAddress, - size_t Length, - uint64_t Flags, - MapType Type = MapType::FourKiB) - { - int PageSize = PAGE_SIZE_4K; - - if (Type == MapType::TwoMiB) - PageSize = PAGE_SIZE_2M; - else if (Type == MapType::FourMiB) - PageSize = PAGE_SIZE_4M; - else if (Type == MapType::OneGiB) - PageSize = PAGE_SIZE_1G; - - for (uintptr_t i = 0; i < Length; i += PageSize) - { - this->Map((void *)((uintptr_t)VirtualAddress + i), - (void *)((uintptr_t)PhysicalAddress + i), - Flags, Type); - } - } - - /** - * @brief Map multiple pages efficiently. - * - * This function will detect the best page size to map the pages. - * - * @note This function will not check if PSE or 1GB pages are enabled or supported. - * - * @param VirtualAddress First virtual address of the page. - * @param PhysicalAddress First physical address of the page. - * @param Length Length of the pages. - * @param Flags Flags of the page. Check PTFlag enum. - * @param Fit If true, the function will try to fit the pages in the smallest page size. - * @param FailOnModulo If true, the function will return NoMapType if the length is not a multiple of the page size. - * @return The best page size to map the pages. - */ - __always_inline inline MapType OptimizedMap(void *VirtualAddress, - void *PhysicalAddress, - size_t Length, - uint64_t Flags, - bool Fit = false, - bool FailOnModulo = false) - { - if (unlikely(Fit)) - { - while (Length >= PAGE_SIZE_1G) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::OneGiB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_1G); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_1G); - Length -= PAGE_SIZE_1G; - } - - while (Length >= PAGE_SIZE_4M) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::FourMiB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_4M); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_4M); - Length -= PAGE_SIZE_4M; - } - - while (Length >= PAGE_SIZE_2M) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::TwoMiB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_2M); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_2M); - Length -= PAGE_SIZE_2M; - } - - while (Length >= PAGE_SIZE_4K) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::FourKiB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_4K); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_4K); - Length -= PAGE_SIZE_4K; - } - - return Virtual::MapType::FourKiB; - } - - Virtual::MapType Type = Virtual::MapType::FourKiB; - - if (Length >= PAGE_SIZE_1G) - { - Type = Virtual::MapType::OneGiB; - if (Length % PAGE_SIZE_1G != 0) - { - warn("Length is not a multiple of 1GB."); - if (FailOnModulo) - return Virtual::MapType::NoMapType; - } - } - else if (Length >= PAGE_SIZE_4M) - { - Type = Virtual::MapType::FourMiB; - if (Length % PAGE_SIZE_4M != 0) - { - warn("Length is not a multiple of 4MB."); - if (FailOnModulo) - return Virtual::MapType::NoMapType; - } - } - else if (Length >= PAGE_SIZE_2M) - { - Type = Virtual::MapType::TwoMiB; - if (Length % PAGE_SIZE_2M != 0) - { - warn("Length is not a multiple of 2MB."); - if (FailOnModulo) - return Virtual::MapType::NoMapType; - } - } - - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Type); - return Type; - } - - /** - * @brief Unmap page. - * - * @param VirtualAddress Virtual address of the page. - * @param Type Type of the page. Check MapType enum. - */ - void Unmap(void *VirtualAddress, MapType Type = MapType::FourKiB); - - /** - * @brief Unmap multiple pages. - * - * @param VirtualAddress First virtual address of the page. - * @param Length Length to map. - * @param Type Type of the page. Check MapType enum. - */ - __always_inline inline void Unmap(void *VirtualAddress, size_t Length, MapType Type = MapType::FourKiB) - { - int PageSize = PAGE_SIZE_4K; - - if (Type == MapType::TwoMiB) - PageSize = PAGE_SIZE_2M; - else if (Type == MapType::FourMiB) - PageSize = PAGE_SIZE_4M; - else if (Type == MapType::OneGiB) - PageSize = PAGE_SIZE_1G; - - for (uintptr_t i = 0; i < Length; i += PageSize) - this->Unmap((void *)((uintptr_t)VirtualAddress + i), Type); - } - - /** - * @brief Remap page. - * - * @param VirtualAddress Virtual address of the page. - * @param PhysicalAddress Physical address of the page. - * @param Flags Flags of the page. Check PTFlag enum. - * @param Type Type of the page. Check MapType enum. - */ - __always_inline inline void Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type = MapType::FourKiB) - { - this->Unmap(VirtualAddress, Type); - this->Map(VirtualAddress, PhysicalAddress, Flags, Type); - } - - /** - * @brief Construct a new Virtual object - * - * @param Table Page table. If null, it will use the current page table. - */ - Virtual(PageTable *Table = nullptr); - - /** - * @brief Destroy the Virtual object - * - */ - ~Virtual(); - }; - - class StackGuard - { - private: - struct AllocatedPages - { - void *PhysicalAddress; - void *VirtualAddress; - }; - - void *StackBottom = nullptr; - void *StackTop = nullptr; - void *StackPhysicalBottom = nullptr; - void *StackPhysicalTop = nullptr; - uint64_t Size = 0; - bool UserMode = false; - bool Expanded = false; - PageTable *Table = nullptr; - std::vector AllocatedPagesList; - - public: - std::vector GetAllocatedPages() { return AllocatedPagesList; } - - /** @brief Fork stack guard */ - void Fork(StackGuard *Parent); - - /** @brief For general info */ - uint64_t GetSize() { return Size; } - - /** @brief For general info */ - bool GetUserMode() { return UserMode; } - - /** @brief For general info */ - bool IsExpanded() { return Expanded; } - - /** @brief For general info */ - void *GetStackBottom() { return StackBottom; } - - /** @brief For RSP */ - void *GetStackTop() { return StackTop; } - - /** @brief For general info (avoid if possible) - * @note This can be used only if the stack was NOT expanded. - */ - void *GetStackPhysicalBottom() - { - if (Expanded) - return nullptr; - return StackPhysicalBottom; - } - - /** @brief For general info (avoid if possible) - * @note This can be used only if the stack was NOT expanded. - */ - void *GetStackPhysicalTop() - { - if (Expanded) - return nullptr; - return StackPhysicalTop; - } - - /** @brief Called by exception handler */ - bool Expand(uintptr_t FaultAddress); - /** - * @brief Construct a new Stack Guard object - * @param User Stack for user mode? - */ - StackGuard(bool User, PageTable *Table); - /** - * @brief Destroy the Stack Guard object - */ - ~StackGuard(); - }; - - class MemMgr - { - public: - struct AllocatedPages - { - void *Address; - std::size_t PageCount; - }; - - std::vector GetAllocatedPagesList() { return AllocatedPagesList; } - uint64_t GetAllocatedMemorySize(); - - bool Add(void *Address, size_t Count); - - void *RequestPages(std::size_t Count, bool User = false); - void FreePages(void *Address, size_t Count); - - void DetachAddress(void *Address); - - MemMgr(PageTable *Table = nullptr, VirtualFileSystem::Node *Directory = nullptr); - ~MemMgr(); - - private: - NewLock(MgrLock); - Bitmap PageBitmap; - PageTable *Table; - VirtualFileSystem::Node *Directory; - - std::vector AllocatedPagesList; - }; - - class ProgramBreak - { - private: - PageTable *Table = nullptr; - MemMgr *mm = nullptr; - - uintptr_t HeapStart = 0x0; - uintptr_t Break = 0x0; - - public: - /* Directly to syscall */ - void *brk(void *Address); - - void InitBrk(uintptr_t Address) - { - function("%#lx", Address); - HeapStart = Address; - Break = Address; - } - - ProgramBreak(PageTable *Table, MemMgr *mm); - ~ProgramBreak(); - }; - - class SmartHeap - { - private: - void *Object = nullptr; - std::size_t ObjectSize = 0; - - public: - auto GetObject() { return Object; } - SmartHeap(std::size_t Size); - ~SmartHeap(); - - void *operator->() { return Object; } - void *operator*() { return Object; } - operator void *() { return Object; } - operator const char *() - { - return r_cst(const char *, Object); - } - void operator=(void *Address) - { - memcpy(Object, Address, ObjectSize); - } - }; } +#include +#include +#include +#include +#include +#include +#include +#include +#include + void InitializeMemoryManagement(); void *operator new(std::size_t Size); diff --git a/include/memory/brk.hpp b/include/memory/brk.hpp new file mode 100644 index 00000000..b80c4fd2 --- /dev/null +++ b/include/memory/brk.hpp @@ -0,0 +1,54 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_PROGRAM_BREAK_H__ +#define __FENNIX_KERNEL_MEMORY_PROGRAM_BREAK_H__ + +#include +#include + +#include +#include + +namespace Memory +{ + class ProgramBreak + { + private: + PageTable *Table = nullptr; + VirtualMemoryArea *vma = nullptr; + + uintptr_t HeapStart = 0x0; + uintptr_t Break = 0x0; + + public: + /* Directly to syscall */ + void *brk(void *Address); + + void InitBrk(uintptr_t Address) + { + function("%#lx", Address); + HeapStart = Address; + Break = Address; + } + + ProgramBreak(PageTable *Table, VirtualMemoryArea *mm); + ~ProgramBreak(); + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_PROGRAM_BREAK_H__ diff --git a/include/memory/macro.hpp b/include/memory/macro.hpp new file mode 100644 index 00000000..2543df04 --- /dev/null +++ b/include/memory/macro.hpp @@ -0,0 +1,60 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_MACROS_H__ +#define __FENNIX_KERNEL_MEMORY_MACROS_H__ + +#include + +// kilobyte +#define TO_KiB(d) ((d) / 1024) +// megabyte +#define TO_MiB(d) ((d) / 1024 / 1024) +// gigabyte +#define TO_GiB(d) ((d) / 1024 / 1024 / 1024) +// terabyte +#define TO_TiB(d) ((d) / 1024 / 1024 / 1024 / 1024) +// petabyte +#define TO_PiB(d) ((d) / 1024 / 1024 / 1024 / 1024 / 1024) +// exobyte +#define TO_EiB(d) ((d) / 1024 / 1024 / 1024 / 1024 / 1024 / 1024) + +#define PAGE_SIZE 0x1000 // 4KB +#define PAGE_SIZE_4K PAGE_SIZE // 4KB +#define PAGE_SIZE_2M 0x200000 // 2MB +#define PAGE_SIZE_4M 0x400000 // 4MB +#define PAGE_SIZE_1G 0x40000000 // 1GB + +#define STACK_SIZE 0x4000 // 16kb +#define USER_STACK_SIZE 0x2000 // 8kb + +// To pages +#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE) +// From pages +#define FROM_PAGES(d) ((d) * PAGE_SIZE) + +#if defined(a64) || defined(aa64) +#define KERNEL_VMA_OFFSET 0xFFFFFFFF80000000 +#define KERNEL_HEAP_BASE 0xFFFFFF0000000000 +#define USER_STACK_BASE 0xFFFFEFFFFFFF0000 +#elif defined(a32) +#define KERNEL_VMA_OFFSET 0xC0000000 +#define KERNEL_HEAP_BASE 0xA0000000 +#define USER_STACK_BASE 0xEFFFFFFF +#endif + +#endif // !__FENNIX_KERNEL_MEMORY_MACROS_H__ diff --git a/include/memory/physical.hpp b/include/memory/physical.hpp new file mode 100644 index 00000000..33aca97b --- /dev/null +++ b/include/memory/physical.hpp @@ -0,0 +1,174 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_PHYSICAL_H__ +#define __FENNIX_KERNEL_MEMORY_PHYSICAL_H__ + +#include + +#include +#include + +namespace Memory +{ + class Physical + { + private: + NewLock(MemoryLock); + + std::atomic_uint64_t TotalMemory = 0; + std::atomic_uint64_t FreeMemory = 0; + std::atomic_uint64_t ReservedMemory = 0; + std::atomic_uint64_t UsedMemory = 0; + uint64_t PageBitmapIndex = 0; + Bitmap PageBitmap; + + void ReserveEssentials(); + void FindBitmapRegion(uintptr_t &BitmapAddress, + size_t &BitmapAddressSize); + + public: + Bitmap GetPageBitmap() { return PageBitmap; } + + /** + * @brief Get Total Memory + * + * @return uint64_t + */ + uint64_t GetTotalMemory(); + + /** + * @brief Get Free Memory + * + * @return uint64_t + */ + uint64_t GetFreeMemory(); + + /** + * @brief Get Reserved Memory + * + * @return uint64_t + */ + uint64_t GetReservedMemory(); + + /** + * @brief Get Used Memory + * + * @return uint64_t + */ + uint64_t GetUsedMemory(); + + /** + * @brief Swap page + * + * @param Address Address of the page + * @return true if swap was successful + * @return false if swap was unsuccessful + */ + bool SwapPage(void *Address); + + /** + * @brief Swap pages + * + * @param Address Address of the pages + * @param PageCount Number of pages + * @return true if swap was successful + * @return false if swap was unsuccessful + */ + bool SwapPages(void *Address, size_t PageCount); + + /** + * @brief Unswap page + * + * @param Address Address of the page + * @return true if unswap was successful + * @return false if unswap was unsuccessful + */ + bool UnswapPage(void *Address); + + /** + * @brief Unswap pages + * + * @param Address Address of the pages + * @param PageCount Number of pages + * @return true if unswap was successful + * @return false if unswap was unsuccessful + */ + bool UnswapPages(void *Address, size_t PageCount); + + /** + * @brief Lock page + * + * @param Address Address of the page + */ + void LockPage(void *Address); + + /** + * @brief Lock pages + * + * @param Address Address of the pages + * @param PageCount Number of pages + */ + void LockPages(void *Address, size_t PageCount); + + void ReservePage(void *Address); + void ReservePages(void *Address, size_t PageCount); + void UnreservePage(void *Address); + void UnreservePages(void *Address, size_t PageCount); + + /** + * @brief Request page + * + * @return void* Allocated page address + */ + void *RequestPage(); + + /** + * @brief Request pages + * + * @param PageCount Number of pages + * @return void* Allocated pages address + */ + void *RequestPages(std::size_t Count); + + /** + * @brief Free page + * + * @param Address Address of the page + */ + void FreePage(void *Address); + + /** + * @brief Free pages + * + * @param Address Address of the pages + * @param PageCount Number of pages + */ + void FreePages(void *Address, size_t Count); + + /** @brief Do not use. */ + void Init(); + + /** @brief Do not use. */ + Physical(); + + /** @brief Do not use. */ + ~Physical(); + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_PHYSICAL_H__ diff --git a/include/memory/smart_heap.hpp b/include/memory/smart_heap.hpp new file mode 100644 index 00000000..a709f405 --- /dev/null +++ b/include/memory/smart_heap.hpp @@ -0,0 +1,67 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_SMART_HEAP_H__ +#define __FENNIX_KERNEL_MEMORY_SMART_HEAP_H__ + +#include +#include +#include +#include + +namespace Memory +{ + class SmartHeap + { + private: + VirtualMemoryArea *vma = nullptr; + void *Object = nullptr; + std::size_t ObjectSize = 0; + + public: + auto Get() { return Object; } + SmartHeap(std::size_t Size, + VirtualMemoryArea *vma = nullptr); + ~SmartHeap(); + + void *operator->() { return Object; } + void *operator*() { return Object; } + operator void *() { return Object; } + + operator const char *() + { + return r_cst(const char *, Object); + } + + operator uintptr_t() + { + return r_cst(uintptr_t, Object); + } + + operator uint8_t *() + { + return r_cst(uint8_t *, Object); + } + + void operator=(void *Address) + { + memcpy(Object, Address, ObjectSize); + } + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_SMART_HEAP_H__ diff --git a/include/memory/stack.hpp b/include/memory/stack.hpp new file mode 100644 index 00000000..2b295d28 --- /dev/null +++ b/include/memory/stack.hpp @@ -0,0 +1,114 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_STACK_GUARD_H__ +#define __FENNIX_KERNEL_MEMORY_STACK_GUARD_H__ + +#include +#include + +#include + +namespace Memory +{ + class StackGuard + { + private: + struct AllocatedPages + { + void *PhysicalAddress; + void *VirtualAddress; + }; + + void *StackBottom = nullptr; + void *StackTop = nullptr; + void *StackPhysicalBottom = nullptr; + void *StackPhysicalTop = nullptr; + uint64_t Size = 0; + bool UserMode = false; + bool Expanded = false; + VirtualMemoryArea *vma = nullptr; + std::vector AllocatedPagesList; + + public: + std::vector GetAllocatedPages() + { + return AllocatedPagesList; + } + + /** Fork stack guard */ + void Fork(StackGuard *Parent); + + /** For general info */ + uint64_t GetSize() { return Size; } + + /** For general info */ + bool GetUserMode() { return UserMode; } + + /** For general info */ + bool IsExpanded() { return Expanded; } + + /** For general info */ + void *GetStackBottom() { return StackBottom; } + + /** For RSP */ + void *GetStackTop() { return StackTop; } + + /** + * For general info (avoid if possible) + * + * @note This can be used only if the + * stack was NOT expanded. + */ + void *GetStackPhysicalBottom() + { + if (Expanded) + return nullptr; + return StackPhysicalBottom; + } + + /** + * For general info (avoid if possible) + * + * @note This can be used only if the + * stack was NOT expanded. + */ + void *GetStackPhysicalTop() + { + if (Expanded) + return nullptr; + return StackPhysicalTop; + } + + /** + * Called by exception handler */ + bool Expand(uintptr_t FaultAddress); + + /** + * Construct a new Stack Guard object + * @param User Stack for user mode? + */ + StackGuard(bool User, VirtualMemoryArea *vma); + + /** + * Destroy the Stack Guard object + */ + ~StackGuard(); + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_STACK_GUARD_H__ diff --git a/include/memory/swap_pt.hpp b/include/memory/swap_pt.hpp new file mode 100644 index 00000000..83c93c30 --- /dev/null +++ b/include/memory/swap_pt.hpp @@ -0,0 +1,52 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_TEMP_PAGE_TABLE_H__ +#define __FENNIX_KERNEL_MEMORY_TEMP_PAGE_TABLE_H__ + +#include + +#include + +extern Memory::PageTable *KernelPageTable; + +namespace Memory +{ + class SwapPT + { + private: + PageTable *Replace = nullptr; + PageTable *Restore = nullptr; + + public: + SwapPT(PageTable *ReplaceWith, + PageTable *RestoreWith = nullptr) + : Replace(ReplaceWith) + { + if (RestoreWith) + Restore = RestoreWith; + else + Restore = KernelPageTable; + + Replace->Update(); + } + + ~SwapPT() { Restore->Update(); } + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_TEMP_PAGE_TABLE_H__ diff --git a/include/memory/table.hpp b/include/memory/table.hpp new file mode 100644 index 00000000..b007dc07 --- /dev/null +++ b/include/memory/table.hpp @@ -0,0 +1,526 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_TABLE_H__ +#define __FENNIX_KERNEL_MEMORY_TABLE_H__ + +#include + +namespace Memory +{ + /** + * @brief https://wiki.osdev.org/images/4/41/64-bit_page_tables1.png + * @brief https://wiki.osdev.org/images/6/6b/64-bit_page_tables2.png + */ + enum PTFlag + { + /** @brief Present */ + P = 1 << 0, + + /** @brief Read/Write */ + RW = 1 << 1, + + /** @brief User/Supervisor */ + US = 1 << 2, + + /** @brief Write-Through */ + PWT = 1 << 3, + + /** @brief Cache Disable */ + PCD = 1 << 4, + + /** @brief Accessed */ + A = 1 << 5, + + /** @brief Dirty */ + D = 1 << 6, + + /** @brief Page Size */ + PS = 1 << 7, + + /** @brief Global */ + G = 1 << 8, + + /** @brief Available 0 */ + CoW = 1 << 9, + + /** @brief Available 1 */ + AVL1 = 1 << 10, + + /** @brief Available 2 */ + AVL2 = 1 << 11, + + /** @brief Page Attribute Table */ + PAT = 1 << 12, + + /** @brief Available 3 */ + AVL3 = (uint64_t)1 << 52, + + /** @brief Available 4 */ + AVL4 = (uint64_t)1 << 53, + + /** @brief Available 5 */ + AVL5 = (uint64_t)1 << 54, + + /** @brief Available 6 */ + AVL6 = (uint64_t)1 << 55, + + /** @brief Available 7 */ + AVL7 = (uint64_t)1 << 56, + + /** @brief Available 8 */ + AVL8 = (uint64_t)1 << 57, + + /** @brief Available 9 */ + AVL9 = (uint64_t)1 << 58, + + /** @brief Protection Key 0 */ + PK0 = (uint64_t)1 << 59, + + /** @brief Protection Key 1 */ + PK1 = (uint64_t)1 << 60, + + /** @brief Protection Key 2 */ + PK2 = (uint64_t)1 << 61, + + /** @brief Protection Key 3 */ + PK3 = (uint64_t)1 << 62, + + /** @brief Execute Disable */ + XD = (uint64_t)1 << 63 + }; + + union __packed PageTableEntry + { + struct + { +#if defined(a64) + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t Dirty : 1; // 6 + uintptr_t PageAttributeTable : 1; // 7 + uintptr_t Global : 1; // 8 + uintptr_t CopyOnWrite : 1; // 9 + uintptr_t Available1 : 1; // 10 + uintptr_t Available2 : 1; // 11 + uintptr_t Address : 40; // 12-51 + uintptr_t Available3 : 1; // 52 + uintptr_t Available4 : 1; // 53 + uintptr_t Available5 : 1; // 54 + uintptr_t Available6 : 1; // 55 + uintptr_t Available7 : 1; // 56 + uintptr_t Available8 : 1; // 57 + uintptr_t Available9 : 1; // 58 + uintptr_t ProtectionKey : 4; // 59-62 + uintptr_t ExecuteDisable : 1; // 63 +#elif defined(a32) + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t Dirty : 1; // 6 + uintptr_t PageAttributeTable : 1; // 7 + uintptr_t Global : 1; // 8 + uintptr_t CopyOnWrite : 1; // 9 + uintptr_t Available1 : 1; // 10 + uintptr_t Available2 : 1; // 11 + uintptr_t Address : 20; // 12-31 +#elif defined(aa64) +#endif + }; + uintptr_t raw; + + /** @brief Set Address */ + void SetAddress(uintptr_t _Address) + { +#if defined(a64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(a32) + _Address &= 0x000FFFFF; + this->raw &= 0xFFC00003; + this->raw |= (_Address << 12); +#elif defined(aa64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get Address */ + uintptr_t GetAddress() + { +#if defined(a64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(a32) + return ((uintptr_t)(this->raw & 0x003FFFFF000) >> 12); +#elif defined(aa64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct __packed PageTableEntryPtr + { +#if defined(a64) + PageTableEntry Entries[512]; +#elif defined(a32) + PageTableEntry Entries[1024]; +#elif defined(aa64) +#endif + }; + + union __packed PageDirectoryEntry + { +#if defined(a64) + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t CopyOnWrite : 1; // 6 + uintptr_t PageSize : 1; // 7 + uintptr_t Available1 : 4; // 8-11 + uintptr_t Address : 40; // 12-51 + uintptr_t Available2 : 11; // 52-62 + uintptr_t ExecuteDisable : 1; // 63 + }; + + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t Dirty : 1; // 6 + uintptr_t PageSize : 1; // 7 + uintptr_t Global : 1; // 8 + uintptr_t CopyOnWrite : 1; // 9 + uintptr_t Available1 : 1; // 10 + uintptr_t Available2 : 1; // 11 + uintptr_t PageAttributeTable : 1; // 12 + uintptr_t Reserved0 : 8; // 13-20 + uintptr_t Address : 31; // 21-51 + uintptr_t Available3 : 1; // 52 + uintptr_t Available4 : 1; // 53 + uintptr_t Available5 : 1; // 54 + uintptr_t Available6 : 1; // 55 + uintptr_t Available7 : 1; // 56 + uintptr_t Available8 : 1; // 57 + uintptr_t Available9 : 1; // 58 + uintptr_t ProtectionKey : 4; // 59-62 + uintptr_t ExecuteDisable : 1; // 63 + } TwoMiB; +#elif defined(a32) + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t CopyOnWrite : 1; // 6 + uintptr_t PageSize : 1; // 7 + uintptr_t Available1 : 4; // 8-11 + uintptr_t Address : 20; // 12-31 + }; + + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t Dirty : 1; // 6 + uintptr_t PageSize : 1; // 7 + uintptr_t Global : 1; // 8 + uintptr_t CopyOnWrite : 1; // 9 + uintptr_t Available1 : 1; // 10 + uintptr_t Available2 : 1; // 11 + uintptr_t PageAttributeTable : 1; // 12 + uintptr_t Address0 : 8; // 13-20 + uintptr_t Reserved0 : 1; // 21 + uintptr_t Address1 : 10; // 22-31 + } FourMiB; +#elif defined(aa64) +#endif + uintptr_t raw; + + /** @brief Set PageTableEntryPtr address */ + void SetAddress(uintptr_t _Address) + { +#if defined(a64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(a32) + _Address &= 0x000FFFFF; + this->raw &= 0xFFC00003; + this->raw |= (_Address << 12); +#elif defined(aa64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageTableEntryPtr address */ + uintptr_t GetAddress() + { +#if defined(a64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(a32) + return ((uintptr_t)(this->raw & 0x003FFFFF000) >> 12); +#elif defined(aa64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct __packed PageDirectoryEntryPtr + { + PageDirectoryEntry Entries[512]; + }; + + union __packed PageDirectoryPointerTableEntry + { +#if defined(a64) + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t CopyOnWrite : 1; // 6 + uintptr_t PageSize : 1; // 7 + uintptr_t Available1 : 4; // 8-11 + uintptr_t Address : 40; // 12-51 + uintptr_t Available2 : 11; // 52-62 + uintptr_t ExecuteDisable : 1; // 63 + }; + + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t Dirty : 1; // 6 + uintptr_t PageSize : 1; // 7 + uintptr_t Global : 1; // 8 + uintptr_t CopyOnWrite : 1; // 9 + uintptr_t Available1 : 1; // 10 + uintptr_t Available2 : 1; // 11 + uintptr_t PageAttributeTable : 1; // 12 + uintptr_t Reserved0 : 17; // 13-29 + uintptr_t Address : 22; // 30-51 + uintptr_t Available3 : 1; // 52 + uintptr_t Available4 : 1; // 53 + uintptr_t Available5 : 1; // 54 + uintptr_t Available6 : 1; // 55 + uintptr_t Available7 : 1; // 56 + uintptr_t Available8 : 1; // 57 + uintptr_t Available9 : 1; // 58 + uintptr_t ProtectionKey : 4; // 59-62 + uintptr_t ExecuteDisable : 1; // 63 + } OneGiB; +#elif defined(aa64) +#endif + uintptr_t raw; + + /** @brief Set PageDirectoryEntryPtr address */ + void SetAddress(uintptr_t _Address) + { +#if defined(a64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(aa64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageDirectoryEntryPtr address */ + uintptr_t GetAddress() + { +#if defined(a64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(a32) + return 0; +#elif defined(aa64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct __packed PageDirectoryPointerTableEntryPtr + { + PageDirectoryPointerTableEntry Entries[512]; + }; + + union __packed PageMapLevel4 + { +#if defined(a64) + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t CopyOnWrite : 1; // 6 + uintptr_t Reserved0 : 1; // 7 + uintptr_t Available1 : 4; // 8-11 + uintptr_t Address : 40; // 12-51 + uintptr_t Available2 : 11; // 52-62 + uintptr_t ExecuteDisable : 1; // 63 + }; +#elif defined(aa64) +#endif + uintptr_t raw; + + /** @brief Set PageDirectoryPointerTableEntryPtr address */ + void SetAddress(uintptr_t _Address) + { +#if defined(a64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(aa64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageDirectoryPointerTableEntryPtr address */ + uintptr_t GetAddress() + { +#if defined(a64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(a32) + return 0; +#elif defined(aa64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct __packed PageMapLevel4Ptr + { + PageMapLevel4 Entries[512]; + }; + + union __packed PageMapLevel5 + { +#if defined(a64) + struct + { + uintptr_t Present : 1; // 0 + uintptr_t ReadWrite : 1; // 1 + uintptr_t UserSupervisor : 1; // 2 + uintptr_t WriteThrough : 1; // 3 + uintptr_t CacheDisable : 1; // 4 + uintptr_t Accessed : 1; // 5 + uintptr_t Available0 : 1; // 6 + uintptr_t Reserved0 : 1; // 7 + uintptr_t Available1 : 4; // 8-11 + uintptr_t Address : 40; // 12-51 + uintptr_t Available2 : 11; // 52-62 + uintptr_t ExecuteDisable : 1; // 63 + }; +#elif defined(aa64) +#endif + uintptr_t raw; + + /** @brief Set PageMapLevel4Ptr address */ + void SetAddress(uintptr_t _Address) + { +#if defined(a64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(aa64) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageMapLevel4Ptr address */ + uintptr_t GetAddress() + { +#if defined(a64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(a32) + return 0; +#elif defined(aa64) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + class PageTable + { + public: +#if defined(a64) + PageMapLevel4 Entries[512]; +#elif defined(a32) + PageDirectoryEntry Entries[1024]; +#elif defined(aa64) +#endif + + /** + * @brief Update CR3 with this PageTable + */ + void Update(); + + /** + * @brief Fork this PageTable + * + * @return A new PageTable with the same content + */ + PageTable Fork(); + + template + T Get(T Address); + } __aligned(0x1000); +} + +#endif // !__FENNIX_KERNEL_MEMORY_TABLE_H__ diff --git a/include/memory/virtual.hpp b/include/memory/virtual.hpp new file mode 100644 index 00000000..bd11e836 --- /dev/null +++ b/include/memory/virtual.hpp @@ -0,0 +1,292 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_VIRTUAL_H__ +#define __FENNIX_KERNEL_MEMORY_VIRTUAL_H__ + +#include +#include + +#include +#include + +namespace Memory +{ + class Virtual + { + private: + NewLock(MemoryLock); + PageTable *Table = nullptr; + + public: + enum MapType + { + NoMapType, + FourKiB, + TwoMiB, + FourMiB, + OneGiB + }; + + class PageMapIndexer + { + public: +#if defined(a64) + uintptr_t PMLIndex = 0; + uintptr_t PDPTEIndex = 0; +#endif + uintptr_t PDEIndex = 0; + uintptr_t PTEIndex = 0; + PageMapIndexer(uintptr_t VirtualAddress); + }; + + /** + * @brief Check if page has the specified flag. + * + * @param VirtualAddress Virtual address of the page + * @param Flag Flag to check + * @param Type Type of the page. Check MapType enum. + * @return true if page has the specified flag. + * @return false if page is has the specified flag. + */ + bool Check(void *VirtualAddress, + PTFlag Flag = PTFlag::P, + MapType Type = MapType::FourKiB); + + /** + * @brief Get physical address of the page. + * @param VirtualAddress Virtual address of the page. + * @return Physical address of the page. + */ + void *GetPhysical(void *VirtualAddress); + + /** + * @brief Get map type of the page. + * @param VirtualAddress Virtual address of the page. + * @return Map type of the page. + */ + MapType GetMapType(void *VirtualAddress); + +#ifdef a64 + PageMapLevel5 *GetPML5(void *VirtualAddress, MapType Type = MapType::FourKiB); + PageMapLevel4 *GetPML4(void *VirtualAddress, MapType Type = MapType::FourKiB); + PageDirectoryPointerTableEntry *GetPDPTE(void *VirtualAddress, MapType Type = MapType::FourKiB); +#endif /* a64 */ + PageDirectoryEntry *GetPDE(void *VirtualAddress, MapType Type = MapType::FourKiB); + PageTableEntry *GetPTE(void *VirtualAddress, MapType Type = MapType::FourKiB); + + /** + * @brief Map page. + * + * @param VirtualAddress Virtual address of the page. + * @param PhysicalAddress Physical address of the page. + * @param Flags Flags of the page. Check PTFlag enum. + * @param Type Type of the page. Check MapType enum. + */ + void Map(void *VirtualAddress, + void *PhysicalAddress, + uint64_t Flag = PTFlag::P, + MapType Type = MapType::FourKiB); + + /** + * @brief Map multiple pages. + * + * @param VirtualAddress First virtual address of the page. + * @param PhysicalAddress First physical address of the page. + * @param Length Length to map. + * @param Flags Flags of the page. Check PTFlag enum. + * @param Type Type of the page. Check MapType enum. + */ + __always_inline inline void Map(void *VirtualAddress, + void *PhysicalAddress, + size_t Length, + uint64_t Flags, + MapType Type = MapType::FourKiB) + { + int PageSize = PAGE_SIZE_4K; + + if (Type == MapType::TwoMiB) + PageSize = PAGE_SIZE_2M; + else if (Type == MapType::FourMiB) + PageSize = PAGE_SIZE_4M; + else if (Type == MapType::OneGiB) + PageSize = PAGE_SIZE_1G; + + for (uintptr_t i = 0; i < Length; i += PageSize) + { + this->Map((void *)((uintptr_t)VirtualAddress + i), + (void *)((uintptr_t)PhysicalAddress + i), + Flags, Type); + } + } + + /** + * @brief Map multiple pages efficiently. + * + * This function will detect the best page size to map the pages. + * + * @note This function will not check if PSE or 1GB pages are enabled or supported. + * + * @param VirtualAddress First virtual address of the page. + * @param PhysicalAddress First physical address of the page. + * @param Length Length of the pages. + * @param Flags Flags of the page. Check PTFlag enum. + * @param Fit If true, the function will try to fit the pages in the smallest page size. + * @param FailOnModulo If true, the function will return NoMapType if the length is not a multiple of the page size. + * @return The best page size to map the pages. + */ + __always_inline inline MapType OptimizedMap(void *VirtualAddress, + void *PhysicalAddress, + size_t Length, + uint64_t Flags, + bool Fit = false, + bool FailOnModulo = false) + { + if (unlikely(Fit)) + { + while (Length >= PAGE_SIZE_1G) + { + this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::OneGiB); + VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_1G); + PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_1G); + Length -= PAGE_SIZE_1G; + } + + while (Length >= PAGE_SIZE_4M) + { + this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::FourMiB); + VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_4M); + PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_4M); + Length -= PAGE_SIZE_4M; + } + + while (Length >= PAGE_SIZE_2M) + { + this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::TwoMiB); + VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_2M); + PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_2M); + Length -= PAGE_SIZE_2M; + } + + while (Length >= PAGE_SIZE_4K) + { + this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::FourKiB); + VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_4K); + PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_4K); + Length -= PAGE_SIZE_4K; + } + + return Virtual::MapType::FourKiB; + } + + Virtual::MapType Type = Virtual::MapType::FourKiB; + + if (Length >= PAGE_SIZE_1G) + { + Type = Virtual::MapType::OneGiB; + if (Length % PAGE_SIZE_1G != 0) + { + warn("Length is not a multiple of 1GB."); + if (FailOnModulo) + return Virtual::MapType::NoMapType; + } + } + else if (Length >= PAGE_SIZE_4M) + { + Type = Virtual::MapType::FourMiB; + if (Length % PAGE_SIZE_4M != 0) + { + warn("Length is not a multiple of 4MB."); + if (FailOnModulo) + return Virtual::MapType::NoMapType; + } + } + else if (Length >= PAGE_SIZE_2M) + { + Type = Virtual::MapType::TwoMiB; + if (Length % PAGE_SIZE_2M != 0) + { + warn("Length is not a multiple of 2MB."); + if (FailOnModulo) + return Virtual::MapType::NoMapType; + } + } + + this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Type); + return Type; + } + + /** + * @brief Unmap page. + * + * @param VirtualAddress Virtual address of the page. + * @param Type Type of the page. Check MapType enum. + */ + void Unmap(void *VirtualAddress, MapType Type = MapType::FourKiB); + + /** + * @brief Unmap multiple pages. + * + * @param VirtualAddress First virtual address of the page. + * @param Length Length to map. + * @param Type Type of the page. Check MapType enum. + */ + __always_inline inline void Unmap(void *VirtualAddress, size_t Length, MapType Type = MapType::FourKiB) + { + int PageSize = PAGE_SIZE_4K; + + if (Type == MapType::TwoMiB) + PageSize = PAGE_SIZE_2M; + else if (Type == MapType::FourMiB) + PageSize = PAGE_SIZE_4M; + else if (Type == MapType::OneGiB) + PageSize = PAGE_SIZE_1G; + + for (uintptr_t i = 0; i < Length; i += PageSize) + this->Unmap((void *)((uintptr_t)VirtualAddress + i), Type); + } + + /** + * @brief Remap page. + * + * @param VirtualAddress Virtual address of the page. + * @param PhysicalAddress Physical address of the page. + * @param Flags Flags of the page. Check PTFlag enum. + * @param Type Type of the page. Check MapType enum. + */ + __always_inline inline void Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type = MapType::FourKiB) + { + this->Unmap(VirtualAddress, Type); + this->Map(VirtualAddress, PhysicalAddress, Flags, Type); + } + + /** + * @brief Construct a new Virtual object + * + * @param Table Page table. If null, it will use the current page table. + */ + Virtual(PageTable *Table = nullptr); + + /** + * @brief Destroy the Virtual object + * + */ + ~Virtual(); + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_VIRTUAL_H__ diff --git a/include/memory/vma.hpp b/include/memory/vma.hpp new file mode 100644 index 00000000..7c62ca6b --- /dev/null +++ b/include/memory/vma.hpp @@ -0,0 +1,102 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MEMORY_VMA_H__ +#define __FENNIX_KERNEL_MEMORY_VMA_H__ + +#include +#include +#include +#include +#include + +#include + +namespace Memory +{ + class VirtualMemoryArea + { + public: + struct AllocatedPages + { + void *Address; + size_t PageCount; + }; + + struct SharedRegion + { + void *Address = nullptr; + bool Read = 0, Write = 0, Exec = 0; + bool Fixed = 0, Shared = 0; + size_t Length = 0; + size_t ReferenceCount = 0; + }; + + private: + NewLock(MgrLock); + Bitmap PageBitmap; + PageTable *Table; + + std::vector AllocatedPagesList; + std::vector SharedRegions; + + public: + PageTable *GetTable() { return Table; } + + std::vector GetAllocatedPagesList() + { + return AllocatedPagesList; + } + + std::vector GetSharedRegions() + { + return SharedRegions; + } + + uint64_t GetAllocatedMemorySize(); + + bool Add(void *Address, size_t Count); + + void *RequestPages(size_t Count, bool User = false); + void FreePages(void *Address, size_t Count); + void DetachAddress(void *Address); + + /** + * Create a Copy-on-Write region + * + * @param Address Hint address + * @param Length Length of the region + * @param Read Make the region readable + * @param Write Make the region writable + * @param Exec Make the region executable + * @param Fixed Fixed address + * @param Shared Shared region + * @return Address of the region + */ + void *CreateCoWRegion(void *Address, + size_t Length, + bool Read, bool Write, bool Exec, + bool Fixed, bool Shared); + + bool HandleCoW(uintptr_t PFA); + + VirtualMemoryArea(PageTable *Table = nullptr); + ~VirtualMemoryArea(); + }; +} + +#endif // !__FENNIX_KERNEL_MEMORY_VMA_H__ diff --git a/include/module.hpp b/include/module.hpp new file mode 100644 index 00000000..f338a522 --- /dev/null +++ b/include/module.hpp @@ -0,0 +1,235 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_MODULE_H__ +#define __FENNIX_KERNEL_MODULE_H__ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Module +{ + enum ModuleCode + { + /* This must be the same as in mapi.hpp ModuleReturnCode */ + ERROR, + OK, + NOT_IMPLEMENTED, + NOT_FOUND, + NOT_READY, + NOT_AVAILABLE, + NOT_AUTHORIZED, + NOT_VALID, + NOT_ACCEPTED, + INVALID_PCI_BAR, + INVALID_KERNEL_API, + INVALID_MEMORY_ALLOCATION, + INVALID_DATA, + DEVICE_NOT_SUPPORTED, + SYSTEM_NOT_SUPPORTED, + KERNEL_API_VERSION_NOT_SUPPORTED, + + /* End of module-only errors */ + + INVALID_FEX_HEADER, + INVALID_MODULE_DATA, + NOT_MODULE, + MODULE_RETURNED_ERROR, + UNKNOWN_MODULE_TYPE, + UNKNOWN_MODULE_BIND_TYPE, + PCI_DEVICE_NOT_FOUND, + MODULE_CONFLICT + }; + + class ModuleInterruptHook; + struct ModuleFile + { + bool Enabled = false; + bool BuiltIn = false; + unsigned int modUniqueID = 0; + void *Address = nullptr; + void *ExtendedHeaderAddress = nullptr; + void *InterruptCallback = nullptr; + Memory::VirtualMemoryArea *vma = nullptr; + ModuleInterruptHook *InterruptHook[16]{}; + + bool operator==(const ModuleFile &Other) const + { + return modUniqueID == Other.modUniqueID; + } + }; + + struct BuiltInModuleInfo + { + int (*EntryPoint)(void *); + void *ExtendedHeader; + }; + + class ModuleInterruptHook : public Interrupts::Handler + { + private: + NewLock(DriverInterruptLock); + + ModuleFile Handle; + bool Enabled = true; + +#if defined(a64) + void OnInterruptReceived(CPU::x64::TrapFrame *Frame); +#elif defined(a32) + void OnInterruptReceived(CPU::x32::TrapFrame *Frame); +#elif defined(aa64) + void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame); +#endif + + public: + void Enable() { Enabled = true; } + void Disable() { Enabled = false; } + bool IsEnabled() { return Enabled; } + ModuleInterruptHook(int Interrupt, ModuleFile Handle); + virtual ~ModuleInterruptHook() = default; + }; + + class Module + { + private: + NewLock(ModuleInitLock); + + std::vector Modules; + unsigned int modUIDs = 0; + /* If BuiltIn is true, the "fex" is the entry point. */ + ModuleCode CallModuleEntryPoint(void *fex, bool BuiltIn = false); + + public: + /** + * @brief Load and bind a module to a PCI device. + * + * This function will search for a PCI device with the given VendorID and DeviceID. + * If the device is found, the module will be loaded and bound to the device. + * + * @param ModuleAddress The address of the module. The file will be copied to a new location. + * @param Size The size of the module. + * @param IsBuiltIn If the module is built-in, the @param ModuleAddress will be @see BuiltInModuleInfo and the @param Size will be ignored. + * @return ModuleCode The result of the operation. + */ + ModuleCode ModuleLoadBindPCI(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn = false); + + /** + * @brief Load and bind a module to an interrupt. + * + * This function will search for an interrupt with the given IRQ. + * If the interrupt is found, the module will be loaded and bound to the interrupt. + * + * @param ModuleAddress The address of the module. The file will be copied to a new location. + * @param Size The size of the module. + * @param IsBuiltIn If the module is built-in, the @param ModuleAddress will be @see BuiltInModuleInfo and the @param Size will be ignored. + * @return ModuleCode The result of the operation. + */ + ModuleCode ModuleLoadBindInterrupt(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn = false); + + /** + * @brief Load and bind a module to an input device. + * + * This function will attach the module to the input device. + * + * @param ModuleAddress The address of the module. The file will be copied to a new location. + * @param Size The size of the module. + * @param IsBuiltIn If the module is built-in, the @param ModuleAddress will be @see BuiltInModuleInfo and the @param Size will be ignored. + * @return ModuleCode The result of the operation. + */ + ModuleCode ModuleLoadBindInput(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn = false); + + /** + * @brief Load and bind a module to a process. + * + * This function will attach the module to the process. + * + * @param ModuleAddress The address of the module. The file will be copied to a new location. + * @param Size The size of the module. + * @param IsBuiltIn If the module is built-in, the @param ModuleAddress will be @see BuiltInModuleInfo and the @param Size will be ignored. + * @return ModuleCode The result of the operation. + */ + ModuleCode ModuleLoadBindProcess(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn = false); + + /** + * @brief Get the currently loaded drivers. + * + * This function returns a clone of the drivers vector. + * This means that the vector can be modified without affecting the drivers. + * + * @return std::vector A clone of the drivers vector. + */ + std::vector GetModules() { return Modules; } + + /* Reserved by the kernel */ + void Panic(); + + /** + * @brief Unload all drivers. + * + * This function will unload all drivers. + */ + void UnloadAllModules(); + + /** + * @brief Unload a module. + * + * This function will unload a module with the given module unique ID. + * It will free the memory and remove the module from the drivers vector. + * + * @param id The module unique ID. + * @return true If the module was found and unloaded successfully, false otherwise. + */ + bool UnloadModule(unsigned long id); + + /** + * @brief Send a callback to a module. + * + * This function will send a callback to a module with the given module unique ID. + * This is used to communicate with drivers. + * + * @param id The module unique ID. + * @param KCB The @see KernelCallback structure. + * @return int The result of the operation. + */ + int IOCB(unsigned long id, /* KernelCallback */ void *KCB); + + /** + * @brief Load a module. + * @param fildes The file descriptor of the module file. + * @return ModuleCode The result of the operation. + */ + ModuleCode LoadModule(vfs::Node *fildes); + + /* Reserved by the kernel */ + void LoadModules(); + + /* Reserved by the kernel */ + Module(); + + /* Reserved by the kernel */ + ~Module(); + }; +} + +#endif // !__FENNIX_KERNEL_MODULE_H__ diff --git a/include/msexec.h b/include/msexec.h index 4b3fe949..60d28744 100644 --- a/include/msexec.h +++ b/include/msexec.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_MSEXEC_H__ diff --git a/include/net/arp.hpp b/include/net/arp.hpp index 6ea082a8..c97d2e59 100644 --- a/include/net/arp.hpp +++ b/include/net/arp.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_NETWORK_ARP_H__ diff --git a/include/net/dhcp.hpp b/include/net/dhcp.hpp index ed467cf8..82f54e1e 100644 --- a/include/net/dhcp.hpp +++ b/include/net/dhcp.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_DHCP_H__ diff --git a/include/net/dns.hpp b/include/net/dns.hpp index 8cff0bb9..9eb03bfa 100644 --- a/include/net/dns.hpp +++ b/include/net/dns.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_DNS_H__ diff --git a/include/net/eth.hpp b/include/net/eth.hpp index 0030b5b4..cbf24a03 100644 --- a/include/net/eth.hpp +++ b/include/net/eth.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_NETWORK_ETHERNET_H__ @@ -79,7 +79,7 @@ namespace NetworkEthernet public: /** @brief Get driver interface - * @return Driver interface + * @return Module interface */ NetworkInterfaceManager::DeviceInterface *GetInterface() { diff --git a/include/net/icmpv4.hpp b/include/net/icmpv4.hpp index 7611a5cb..fed57c3c 100644 --- a/include/net/icmpv4.hpp +++ b/include/net/icmpv4.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_ICMPv4_H__ diff --git a/include/net/icmpv6.hpp b/include/net/icmpv6.hpp index 9e4dbde0..e4b9b269 100644 --- a/include/net/icmpv6.hpp +++ b/include/net/icmpv6.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_ICMPv6_H__ diff --git a/include/net/ipv4.hpp b/include/net/ipv4.hpp index 820a289b..cfd24122 100644 --- a/include/net/ipv4.hpp +++ b/include/net/ipv4.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_IPv4_H__ diff --git a/include/net/ipv6.hpp b/include/net/ipv6.hpp index f67f3438..b9103899 100644 --- a/include/net/ipv6.hpp +++ b/include/net/ipv6.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_IPv6_H__ diff --git a/include/net/nc.hpp b/include/net/nc.hpp index 04a5675e..92aafbe3 100644 --- a/include/net/nc.hpp +++ b/include/net/nc.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_NETWORK_CONTROLLER_H__ @@ -90,13 +90,13 @@ namespace NetworkInterfaceManager class NetworkInterface { private: - Memory::MemMgr *mem; + Memory::VirtualMemoryArea *vma; int CardIDs = 0; std::vector Interfaces; Tasking::TCB *NetSvcThread; void StopNetworkStack(); - void FetchNetworkCards(unsigned long DriverUID); + void FetchNetworkCards(unsigned long modUniqueID); public: NetworkInterface(); diff --git a/include/net/net.hpp b/include/net/net.hpp index b9074f45..2112abe4 100644 --- a/include/net/net.hpp +++ b/include/net/net.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_NETWORK_H__ diff --git a/include/net/ntp.hpp b/include/net/ntp.hpp index 2ac5bb13..129a91b1 100644 --- a/include/net/ntp.hpp +++ b/include/net/ntp.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_NTP_H__ diff --git a/include/net/tcp.hpp b/include/net/tcp.hpp index 000198b3..83008aa9 100644 --- a/include/net/tcp.hpp +++ b/include/net/tcp.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_TCP_H__ diff --git a/include/net/udp.hpp b/include/net/udp.hpp index 12d7d6e5..1278755f 100644 --- a/include/net/udp.hpp +++ b/include/net/udp.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_UDP_H__ diff --git a/include/pci.hpp b/include/pci.hpp index a0b9d210..0c0881bd 100644 --- a/include/pci.hpp +++ b/include/pci.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_PCI_H__ @@ -220,19 +220,28 @@ namespace PCI uint32_t Reserved; } __packed; + struct PCIDevice + { + PCIDeviceHeader *Header; + DeviceConfig *Config; + uint32_t Bus; + uint32_t Device; + uint32_t Function; + }; + class PCI { private: - std::vector Devices; + std::vector Devices; public: - std::vector &GetDevices() { return Devices; } - void MapPCIAddresses(PCIDeviceHeader *PCIDevice, Memory::PageTable *Table = nullptr); - void EnumerateFunction(uint64_t DeviceAddress, uintptr_t Function); - void EnumerateDevice(uint64_t BusAddress, uintptr_t Device); - void EnumerateBus(uint64_t BaseAddress, uintptr_t Bus); - std::vector FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF); - std::vector FindPCIDevice(int VendorID, int DeviceID); + std::vector &GetDevices() { return Devices; } + void MapPCIAddresses(PCIDevice Device, Memory::PageTable *Table = nullptr); + void EnumerateFunction(uint64_t DeviceAddress, uint32_t Function, PCIDevice dev); + void EnumerateDevice(uint64_t BusAddress, uint32_t Device, PCIDevice dev); + void EnumerateBus(uint64_t BaseAddress, uint32_t Bus, PCIDevice dev); + std::vector FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF); + std::vector FindPCIDevice(int VendorID, int DeviceID); PCI(); ~PCI(); diff --git a/include/power.hpp b/include/power.hpp index be241923..88f27626 100644 --- a/include/power.hpp +++ b/include/power.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_POWER_H__ diff --git a/include/rand.hpp b/include/rand.hpp index 50aa4fa3..7dd941d4 100644 --- a/include/rand.hpp +++ b/include/rand.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_RANDOM_H__ diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 00000000..18884d8d --- /dev/null +++ b/include/signal.h @@ -0,0 +1,194 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_SIGNAL_H__ +#define __FENNIX_KERNEL_SIGNAL_H__ + +#include + +enum Signals +{ + /** + * Process abort signal. + */ + SIGABRT, + + /** + * Alarm clock. + */ + SIGALRM, + + /** + * Access to an undefined portion of a memory object. + */ + SIGBUS, + + /** + * Child process terminated, stopped, + */ + SIGCHLD, + + /** + * Continue executing, if stopped. + */ + SIGCONT, + + /** + * Erroneous arithmetic operation. + */ + SIGFPE, + + /** + * Hangup. + */ + SIGHUP, + + /** + * Illegal instruction. + */ + SIGILL, + + /** + * Terminal interrupt signal. + */ + SIGINT, + + /** + * Kill (cannot be caught or ignored). + */ + SIGKILL, + + /** + * Write on a pipe with no one to read it. + */ + SIGPIPE, + + /** + * Terminal quit signal. + */ + SIGQUIT, + + /** + * Invalid memory reference. + */ + SIGSEGV, + + /** + * Stop executing (cannot be caught or ignored). + */ + SIGSTOP, + + /** + * Termination signal. + */ + SIGTERM, + + /** + * Terminal stop signal. + */ + SIGTSTP, + + /** + * Background process attempting read. + */ + SIGTTIN, + + /** + * Background process attempting write. + */ + SIGTTOU, + + /** + * User-defined signal 1. + */ + SIGUSR1, + + /** + * User-defined signal 2. + */ + SIGUSR2, + + /** + * Pollable event. + */ + SIGPOLL, + + /** + * Profiling timer expired. + */ + SIGPROF, + + /** + * Bad system call. + */ + SIGSYS, + + /** + * Trace/breakpoint trap. + */ + SIGTRAP, + + /** + * High bandwidth data is available at a socket. + */ + SIGURG, + + /** + * Virtual timer expired. + */ + SIGVTALRM, + + /** + * CPU time limit exceeded. + */ + SIGXCPU, + + /** + * File size limit exceeded. + */ + SIGXFSZ, +}; + +union sigval +{ + int sival_int; + void *sival_ptr; +}; + +struct sched_param +{ + int sched_priority; +}; + +struct pthread_attr_t +{ + uint64_t sig; + size_t guard_sz; + bool detach; + sched_param sched; +}; + +struct sigevent +{ + int sigev_notify; + int sigev_signo; + union sigval sigev_value; + void (*sigev_notify_function)(union sigval); + pthread_attr_t *sigev_notify_attributes; +}; + +#endif // !__FENNIX_KERNEL_SIGNAL_H__ diff --git a/include/smart_ptr.hpp b/include/smart_ptr.hpp index 577084f1..8556c335 100644 --- a/include/smart_ptr.hpp +++ b/include/smart_ptr.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include/smp.hpp b/include/smp.hpp index d29f2215..56596b96 100644 --- a/include/smp.hpp +++ b/include/smp.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_SMP_H__ diff --git a/include/symbols.hpp b/include/symbols.hpp index d9e21590..cd7bf268 100644 --- a/include/symbols.hpp +++ b/include/symbols.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include/syscalls.hpp b/include/syscalls.hpp index 419af1ea..072b2134 100644 --- a/include/syscalls.hpp +++ b/include/syscalls.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_SYSCALLS_H__ diff --git a/include/targp.h b/include/targp.h index 4f5a395d..c6991c25 100644 --- a/include/targp.h +++ b/include/targp.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef TinyArgumentParser_H__ diff --git a/include/task.hpp b/include/task.hpp index 60ac230e..c789911a 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_TASKING_H__ @@ -26,14 +26,15 @@ #include #include #include +#include #include #include #include namespace Tasking { - using VirtualFileSystem::FileDescriptorTable; - using VirtualFileSystem::Node; + using vfs::FileDescriptorTable; + using vfs::Node; /** Instruction Pointer */ typedef __UINTPTR_TYPE__ IP; @@ -76,14 +77,71 @@ namespace Tasking _ExecuteModeMax = User }; - enum TaskStatus : int + enum TaskState : int { UnknownStatus, + + /** + * Task ready to be scheduled + */ Ready, + + /** + * Task is the current running task + */ Running, + + /** + * Task is sleeping + * + * Used when the task is waiting for + * a specific amount of time to pass + */ Sleeping, + + /** + * Task is blocked + * + * Used when the task is waiting for + * another task to finish or for an + * event to occur + */ Blocked, + + /** + * Task is stopped + * + * Used when the task is stopped + * by the debugger or by the user + */ + Stopped, + + /** + * Task is waiting + * + * Used when the task is not ready + * to be scheduled by implementation + * e.g. Creating a separate page table + * or waiting for a thread to be created + */ + Waiting, + + /** + * Task is a zombie + * + * Used when the task is waiting + * for the parent to read the exit + * code + */ Zombie, + + /** + * Task is terminated + * + * Used when the task is terminated + * and is waiting to be cleaned up + * by the scheduler + */ Terminated, _StatusMin = UnknownStatus, @@ -127,6 +185,7 @@ namespace Tasking TaskPriority Priority = TaskPriority::Normal; TaskArchitecture Architecture = TaskArchitecture::UnknownArchitecture; TaskCompatibility Compatibility = TaskCompatibility::UnknownPlatform; + cwk_path_style PathStyle = CWK_STYLE_UNIX; }; /** @@ -139,14 +198,18 @@ namespace Tasking * * gs+0x0 */ - uintptr_t SyscallStack = __UINTPTR_MAX__; + uintptr_t SyscallStack; /** * Used by syscall handler * * gs+0x8 */ - uintptr_t TempStack = __UINTPTR_MAX__; + uintptr_t TempStack; + + /* For future use */ + void *SyscallStackBase; + int ScPages; /** * The current thread class @@ -159,6 +222,18 @@ namespace Tasking private: class Task *ctx = nullptr; + /** + * This variable is used to + * store the amount of allocated + * memory for the process. This + * includes the memory allocated + * for the class itself, etc... + * + * @note Allocated memory is + * not the same as used memory. + */ + size_t AllocatedMemory = 0; + void SetupUserStack_x86_64(const char **argv, const char **envp, const std::vector &auxv); @@ -172,6 +247,8 @@ namespace Tasking const std::vector &auxv); public: + class Task *GetContext() { return ctx; } + /* Basic info */ TID ID = -1; const char *Name = nullptr; @@ -180,11 +257,13 @@ namespace Tasking /* Statuses */ std::atomic_int ExitCode; - std::atomic Status = TaskStatus::Zombie; + std::atomic State = TaskState::Waiting; + std::atomic_bool KeepInMemory = false; + std::atomic_size_t KeepTime = 0; int ErrorNumber; /* Memory */ - Memory::MemMgr *Memory; + Memory::VirtualMemoryArea *vma; Memory::StackGuard *Stack; /* CPU state */ @@ -223,9 +302,10 @@ namespace Tasking void SetCritical(bool Critical); void SetDebugMode(bool Enable); void SetKernelDebugMode(bool Enable); + size_t GetSize(); - void Block() { Status.store(TaskStatus::Blocked); } - void Unblock() { Status.store(TaskStatus::Ready); } + void Block() { State.store(TaskState::Blocked); } + void Unblock() { State.store(TaskState::Ready); } void SYSV_ABI_Call(uintptr_t Arg1 = 0, uintptr_t Arg2 = 0, @@ -254,6 +334,18 @@ namespace Tasking class Task *ctx = nullptr; bool OwnPageTable = false; + /** + * This variable is used to + * store the amount of allocated + * memory for the process. This + * includes the memory allocated + * for the class itself, etc... + * + * @note Allocated memory is + * not the same as used memory. + */ + size_t AllocatedMemory = 0; + public: /* Basic info */ PID ID = -1; @@ -262,7 +354,9 @@ namespace Tasking /* Statuses */ std::atomic_int ExitCode; - std::atomic Status = Zombie; + std::atomic State = Waiting; + std::atomic_bool KeepInMemory = false; + std::atomic_size_t KeepTime = 0; /* Info & Security info */ struct @@ -282,12 +376,11 @@ namespace Tasking /* Filesystem */ Node *CurrentWorkingDirectory; Node *ProcessDirectory; - Node *memDirectory; FileDescriptorTable *FileDescriptors; /* Memory */ Memory::PageTable *PageTable; - Memory::MemMgr *Memory; + Memory::VirtualMemoryArea *vma; Memory::ProgramBreak *ProgramBreak; /* Other */ @@ -299,8 +392,11 @@ namespace Tasking std::vector Children; public: + class Task *GetContext() { return ctx; } + void Rename(const char *name); void SetWorkingDirectory(Node *node); + size_t GetSize(); PCB(class Task *ctx, PCB *Parent, @@ -337,14 +433,19 @@ namespace Tasking bool InvalidTCB(TCB *tcb); /** + * Remove a thread from the scheduler + * * @note This function is NOT thread safe + * @note This function does not check if + * the thread is valid nor if it has + * Terminated status */ - void RemoveThread(TCB *tcb); + bool RemoveThread(TCB *tcb); /** * @note This function is NOT thread safe */ - void RemoveProcess(PCB *pcb); + bool RemoveProcess(PCB *pcb); void UpdateUsage(TaskInfo *Info, TaskExecutionMode Mode, @@ -373,7 +474,7 @@ namespace Tasking /** * @note This function is NOT thread safe */ - void UpdateProcessStatus(); + void UpdateProcessState(); /** * @note This function is NOT thread safe @@ -443,7 +544,7 @@ namespace Tasking void KillThread(TCB *tcb, enum KillErrorCodes Code) { - tcb->Status = TaskStatus::Terminated; + tcb->State = TaskState::Terminated; tcb->ExitCode = (int)Code; debug("Killing thread %s(%d) with exit code %d", tcb->Name, tcb->ID, Code); @@ -451,7 +552,7 @@ namespace Tasking void KillProcess(PCB *pcb, enum KillErrorCodes Code) { - pcb->Status = TaskStatus::Terminated; + pcb->State = TaskState::Terminated; pcb->ExitCode = (int)Code; debug("Killing process %s(%d) with exit code %d", pcb->Name, pcb->ID, Code); @@ -479,8 +580,8 @@ namespace Tasking /** Wait for thread to terminate */ void WaitForThread(TCB *tcb); - void WaitForProcessStatus(PCB *pcb, TaskStatus Status); - void WaitForThreadStatus(TCB *tcb, TaskStatus Status); + void WaitForProcessStatus(PCB *pcb, TaskState State); + void WaitForThreadStatus(TCB *tcb, TaskState State); /** * Sleep for a given amount of milliseconds diff --git a/include/time.hpp b/include/time.hpp index 6da7e840..8e271743 100644 --- a/include/time.hpp +++ b/include/time.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_TIME_H__ diff --git a/include/types.h b/include/types.h index 9d02fc14..98065564 100644 --- a/include/types.h +++ b/include/types.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_TYPES_H__ diff --git a/include/uart.hpp b/include/uart.hpp index 5648c516..4cbef0f8 100644 --- a/include/uart.hpp +++ b/include/uart.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_UART_H__ @@ -42,6 +42,7 @@ namespace UniversalAsynchronousReceiverTransmitter { private: SerialPorts Port; + bool IsAvailable; public: UART(SerialPorts Port = COMNULL); diff --git a/include/vm.hpp b/include/vm.hpp index 327957fa..a4323be2 100644 --- a/include/vm.hpp +++ b/include/vm.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_VIRTUALIZATION_H__ @@ -26,10 +26,6 @@ * * @return true if the system is running * in a virtualized environment, false otherwise. - * - * @note This function will check every - * time it is called, so it is recommended - * to call it once and store the result. */ bool IsVirtualizedEnvironment(); diff --git a/include_std/algorithm b/include_std/algorithm index 55e4f7dc..00a7e3cf 100644 --- a/include_std/algorithm +++ b/include_std/algorithm @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/assert.h b/include_std/assert.h index 32444301..51678ae3 100644 --- a/include_std/assert.h +++ b/include_std/assert.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_ASSERT_H__ diff --git a/include_std/atomic b/include_std/atomic index 932851db..54c0b04c 100644 --- a/include_std/atomic +++ b/include_std/atomic @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/cmath b/include_std/cmath index c17ea34a..18668ede 100644 --- a/include_std/cmath +++ b/include_std/cmath @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/cstddef b/include_std/cstddef index f6852ff2..d0fe871a 100644 --- a/include_std/cstddef +++ b/include_std/cstddef @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/cstring b/include_std/cstring index b1a7f207..fe0b0b7d 100644 --- a/include_std/cstring +++ b/include_std/cstring @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/cxxabi.h b/include_std/cxxabi.h index 178e145e..8e468367 100644 --- a/include_std/cxxabi.h +++ b/include_std/cxxabi.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_CXXABI_H__ diff --git a/include_std/dlfcn.h b/include_std/dlfcn.h index 3c5095c7..1114b467 100644 --- a/include_std/dlfcn.h +++ b/include_std/dlfcn.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _DLFCN_H diff --git a/include_std/errno.h b/include_std/errno.h index 23fe8962..96f642cd 100644 --- a/include_std/errno.h +++ b/include_std/errno.h @@ -1,408 +1,408 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _ERRNO_H #define _ERRNO_H -/** @brief Operation not permitted */ +/** Operation not permitted */ #define EPERM 1 -/** @brief No such file or directory */ +/** No such file or directory */ #define ENOENT 2 -/** @brief No such process */ +/** No such process */ #define ESRCH 3 -/** @brief Interrupted system call */ +/** Interrupted system call */ #define EINTR 4 -/** @brief I/O error */ +/** I/O error */ #define EIO 5 -/** @brief No such device or address */ +/** No such device or address */ #define ENXIO 6 -/** @brief Argument list too long */ +/** Argument list too long */ #define E2BIG 7 -/** @brief Exec format error */ +/** Exec format error */ #define ENOEXEC 8 -/** @brief Bad file number */ +/** Bad file number */ #define EBADF 9 -/** @brief No child processes */ +/** No child processes */ #define ECHILD 10 -/** @brief Try again */ +/** Try again */ #define EAGAIN 11 -/** @brief Out of memory */ +/** Out of memory */ #define ENOMEM 12 -/** @brief Permission denied */ +/** Permission denied */ #define EACCES 13 -/** @brief Bad address */ +/** Bad address */ #define EFAULT 14 -/** @brief Block device required */ +/** Block device required */ #define ENOTBLK 15 -/** @brief Device or resource busy */ +/** Device or resource busy */ #define EBUSY 16 -/** @brief File exists */ +/** File exists */ #define EEXIST 17 -/** @brief Cross-device link */ +/** Cross-device link */ #define EXDEV 18 -/** @brief No such device */ +/** No such device */ #define ENODEV 19 -/** @brief Not a directory */ +/** Not a directory */ #define ENOTDIR 20 -/** @brief Is a directory */ +/** Is a directory */ #define EISDIR 21 -/** @brief Invalid argument */ +/** Invalid argument */ #define EINVAL 22 -/** @brief File table overflow */ +/** File table overflow */ #define ENFILE 23 -/** @brief Too many open files */ +/** Too many open files */ #define EMFILE 24 -/** @brief Not a typewriter */ +/** Not a typewriter */ #define ENOTTY 25 -/** @brief Text file busy */ +/** Text file busy */ #define ETXTBSY 26 -/** @brief File too large */ +/** File too large */ #define EFBIG 27 -/** @brief No space left on device */ +/** No space left on device */ #define ENOSPC 28 -/** @brief Illegal seek */ +/** Illegal seek */ #define ESPIPE 29 -/** @brief Read-only file system */ +/** Read-only file system */ #define EROFS 30 -/** @brief Too many links */ +/** Too many links */ #define EMLINK 31 -/** @brief Broken pipe */ +/** Broken pipe */ #define EPIPE 32 -/** @brief Math argument out of domain of func */ +/** Math argument out of domain of func */ #define EDOM 33 -/** @brief Math result not representable */ +/** Math result not representable */ #define ERANGE 34 -/** @brief Resource deadlock would occur */ +/** Resource deadlock would occur */ #define EDEADLK 35 -/** @brief File name too long */ +/** File name too long */ #define ENAMETOOLONG 36 -/** @brief No record locks available */ +/** No record locks available */ #define ENOLCK 37 -/** @brief Function not implemented */ +/** Function not implemented */ #define ENOSYS 38 -/** @brief Directory not empty */ +/** Directory not empty */ #define ENOTEMPTY 39 -/** @brief Too many symbolic links encountered */ +/** Too many symbolic links encountered */ #define ELOOP 40 -/** @brief No message of desired type */ +/** No message of desired type */ #define ENOMSG 42 -/** @brief Identifier removed */ +/** Identifier removed */ #define EIDRM 43 -/** @brief Channel number out of range */ +/** Channel number out of range */ #define ECHRNG 44 -/** @brief Level 2 not synchronized */ +/** Level 2 not synchronized */ #define EL2NSYNC 45 -/** @brief Level 3 halted */ +/** Level 3 halted */ #define EL3HLT 46 -/** @brief Level 3 reset */ +/** Level 3 reset */ #define EL3RST 47 -/** @brief Link number out of range */ +/** Link number out of range */ #define ELNRNG 48 -/** @brief Protocol driver not attached */ +/** Protocol driver not attached */ #define EUNATCH 49 -/** @brief No CSI structure available */ +/** No CSI structure available */ #define ENOCSI 50 -/** @brief Level 2 halted */ +/** Level 2 halted */ #define EL2HLT 51 -/** @brief Invalid exchange */ +/** Invalid exchange */ #define EBADE 52 -/** @brief Invalid request descriptor */ +/** Invalid request descriptor */ #define EBADR 53 -/** @brief Exchange full */ +/** Exchange full */ #define EXFULL 54 -/** @brief No anode */ +/** No anode */ #define ENOANO 55 -/** @brief Invalid request code */ +/** Invalid request code */ #define EBADRQC 56 -/** @brief Invalid slot */ +/** Invalid slot */ #define EBADSLT 57 -/** @brief Bad font file format */ +/** Bad font file format */ #define EBFONT 59 -/** @brief Device not a stream */ +/** Device not a stream */ #define ENOSTR 60 -/** @brief No data available */ +/** No data available */ #define ENODATA 61 -/** @brief Timer expired */ +/** Timer expired */ #define ETIME 62 -/** @brief Out of streams resources */ +/** Out of streams resources */ #define ENOSR 63 -/** @brief Machine is not on the network */ +/** Machine is not on the network */ #define ENONET 64 -/** @brief Package not installed */ +/** Package not installed */ #define ENOPKG 65 -/** @brief Object is remote */ +/** Object is remote */ #define EREMOTE 66 -/** @brief Link has been severed */ +/** Link has been severed */ #define ENOLINK 67 -/** @brief Advertise error */ +/** Advertise error */ #define EADV 68 -/** @brief Srmount error */ +/** Srmount error */ #define ESRMNT 69 -/** @brief Communication error on send */ +/** Communication error on send */ #define ECOMM 70 -/** @brief Protocol error */ +/** Protocol error */ #define EPROTO 71 -/** @brief Multihop attempted */ +/** Multihop attempted */ #define EMULTIHOP 72 -/** @brief RFS specific error */ +/** RFS specific error */ #define EDOTDOT 73 -/** @brief Not a data message */ +/** Not a data message */ #define EBADMSG 74 -/** @brief Value too large for defined data type */ +/** Value too large for defined data type */ #define EOVERFLOW 75 -/** @brief Name not unique on network */ +/** Name not unique on network */ #define ENOTUNIQ 76 -/** @brief File descriptor in bad state */ +/** File descriptor in bad state */ #define EBADFD 77 -/** @brief Remote address changed */ +/** Remote address changed */ #define EREMCHG 78 -/** @brief Can not access a needed shared library */ +/** Can not access a needed shared library */ #define ELIBACC 79 -/** @brief Accessing a corrupted shared library */ +/** Accessing a corrupted shared library */ #define ELIBBAD 80 -/** @brief .lib section in a.out corrupted */ +/** .lib section in a.out corrupted */ #define ELIBSCN 81 -/** @brief Attempting to link in too many shared libraries */ +/** Attempting to link in too many shared libraries */ #define ELIBMAX 82 -/** @brief Cannot exec a shared library directly */ +/** Cannot exec a shared library directly */ #define ELIBEXEC 83 -/** @brief Illegal byte sequence */ +/** Illegal byte sequence */ #define EILSEQ 84 -/** @brief Interrupted system call should be restarted */ +/** Interrupted system call should be restarted */ #define ERESTART 85 -/** @brief Streams pipe error */ +/** Streams pipe error */ #define ESTRPIPE 86 -/** @brief Too many users */ +/** Too many users */ #define EUSERS 87 -/** @brief Socket operation on non-socket */ +/** Socket operation on non-socket */ #define ENOTSOCK 88 -/** @brief Destination address required */ +/** Destination address required */ #define EDESTADDRREQ 89 -/** @brief Message too long */ +/** Message too long */ #define EMSGSIZE 90 -/** @brief Protocol wrong type for socket */ +/** Protocol wrong type for socket */ #define EPROTOTYPE 91 -/** @brief Protocol not available */ +/** Protocol not available */ #define ENOPROTOOPT 92 -/** @brief Protocol not supported */ +/** Protocol not supported */ #define EPROTONOSUPPORT 93 -/** @brief Socket type not supported */ +/** Socket type not supported */ #define ESOCKTNOSUPPORT 94 -/** @brief Operation not supported on transport endpoint */ +/** Operation not supported on transport endpoint */ #define EOPNOTSUPP 95 -/** @brief Protocol family not supported */ +/** Protocol family not supported */ #define EPFNOSUPPORT 96 -/** @brief Address family not supported by protocol */ +/** Address family not supported by protocol */ #define EAFNOSUPPORT 97 -/** @brief Address already in use */ +/** Address already in use */ #define EADDRINUSE 98 -/** @brief Cannot assign requested address */ +/** Cannot assign requested address */ #define EADDRNOTAVAIL 99 -/** @brief Network is down */ +/** Network is down */ #define ENETDOWN 100 -/** @brief Network is unreachable */ +/** Network is unreachable */ #define ENETUNREACH 101 -/** @brief Network dropped connection because of reset */ +/** Network dropped connection because of reset */ #define ENETRESET 102 -/** @brief Software caused connection abort */ +/** Software caused connection abort */ #define ECONNABORTED 103 -/** @brief Connection reset by peer */ +/** Connection reset by peer */ #define ECONNRESET 104 -/** @brief No buffer space available */ +/** No buffer space available */ #define ENOBUFS 105 -/** @brief Transport endpoint is already connected */ +/** Transport endpoint is already connected */ #define EISCONN 106 -/** @brief Transport endpoint is not connected */ +/** Transport endpoint is not connected */ #define ENOTCONN 107 -/** @brief Cannot send after transport endpoint shutdown */ +/** Cannot send after transport endpoint shutdown */ #define ESHUTDOWN 108 -/** @brief Too many references: cannot splice */ +/** Too many references: cannot splice */ #define ETOOMANYREFS 109 -/** @brief Connection timed out */ +/** Connection timed out */ #define ETIMEDOUT 110 -/** @brief Connection refused */ +/** Connection refused */ #define ECONNREFUSED 111 -/** @brief Host is down */ +/** Host is down */ #define EHOSTDOWN 112 -/** @brief No route to host */ +/** No route to host */ #define EHOSTUNREACH 113 -/** @brief Operation already in progress */ +/** Operation already in progress */ #define EALREADY 114 -/** @brief Operation now in progress */ +/** Operation now in progress */ #define EINPROGRESS 115 -/** @brief Stale NFS file handle */ +/** Stale NFS file handle */ #define ESTALE 116 -/** @brief Structure needs cleaning */ +/** Structure needs cleaning */ #define EUCLEAN 117 -/** @brief Not a XENIX named type file */ +/** Not a XENIX named type file */ #define ENOTNAM 118 -/** @brief No XENIX semaphores available */ +/** No XENIX semaphores available */ #define ENAVAIL 119 -/** @brief Is a named type file */ +/** Is a named type file */ #define EISNAM 120 -/** @brief Remote I/O error */ +/** Remote I/O error */ #define EREMOTEIO 121 -/** @brief Quota exceeded */ +/** Quota exceeded */ #define EDQUOT 122 -/** @brief No medium found */ +/** No medium found */ #define ENOMEDIUM 123 -/** @brief Wrong medium type */ +/** Wrong medium type */ #define EMEDIUMTYPE 124 -/** @brief Operation Canceled */ +/** Operation Canceled */ #define ECANCELED 125 -/** @brief Required key not available */ +/** Required key not available */ #define ENOKEY 126 -/** @brief Key has expired */ +/** Key has expired */ #define EKEYEXPIRED 127 -/** @brief Key has been revoked */ +/** Key has been revoked */ #define EKEYREVOKED 128 -/** @brief Key was rejected by service */ +/** Key was rejected by service */ #define EKEYREJECTED 129 -/** @brief Owner died */ +/** Owner died */ #define EOWNERDEAD 130 -/** @brief State not recoverable */ +/** State not recoverable */ #define ENOTRECOVERABLE 131 extern int *__errno_location(void) __attribute__((const)); diff --git a/include_std/exception b/include_std/exception index 75445960..f36b0a67 100644 --- a/include_std/exception +++ b/include_std/exception @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_EXCEPTION_H__ diff --git a/include_std/float.h b/include_std/float.h index ec7b1a4c..666c05fe 100644 --- a/include_std/float.h +++ b/include_std/float.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/functional b/include_std/functional index e2bdcea2..95a52983 100644 --- a/include_std/functional +++ b/include_std/functional @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/limits.h b/include_std/limits.h index 7d61f6af..ed24bdbd 100644 --- a/include_std/limits.h +++ b/include_std/limits.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_LIMITS_H__ @@ -133,4 +133,6 @@ #define BOOL_WIDTH 1 #endif +#define MAX_ARG 0x20000 + #endif // !__FENNIX_KERNEL_LIMITS_H__ diff --git a/include_std/math.h b/include_std/math.h index 18252dfc..f96284ef 100644 --- a/include_std/math.h +++ b/include_std/math.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _MATH_H diff --git a/include_std/mutex b/include_std/mutex index 2b255b04..675412b2 100644 --- a/include_std/mutex +++ b/include_std/mutex @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/pthread.h b/include_std/pthread.h index aec2bc32..672e9c1a 100644 --- a/include_std/pthread.h +++ b/include_std/pthread.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _PTHREAD_H diff --git a/include_std/sched.h b/include_std/sched.h index 56bc215b..4f82fcd4 100644 --- a/include_std/sched.h +++ b/include_std/sched.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _SCHED_H diff --git a/include_std/std.hpp b/include_std/std.hpp index 1a32a8e8..61e32f7a 100644 --- a/include_std/std.hpp +++ b/include_std/std.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ /* This function includes all the standard headers and defines some useful macros. diff --git a/include_std/std/functional.hpp b/include_std/std/functional.hpp index eadf39e5..12c6a4e1 100644 --- a/include_std/std/functional.hpp +++ b/include_std/std/functional.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_FUNCTIONAL_H__ diff --git a/include_std/std/list.hpp b/include_std/std/list.hpp index 2de7557f..5869cb0e 100644 --- a/include_std/std/list.hpp +++ b/include_std/std/list.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_LIST_H__ diff --git a/include_std/std/smart_ptr.hpp b/include_std/std/smart_ptr.hpp index 94c4d58a..f6bc2758 100644 --- a/include_std/std/smart_ptr.hpp +++ b/include_std/std/smart_ptr.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_SMART_POINTER_H__ diff --git a/include_std/std/stdexcept.hpp b/include_std/std/stdexcept.hpp index b243c38c..5f35d502 100644 --- a/include_std/std/stdexcept.hpp +++ b/include_std/std/stdexcept.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_STDEXCEPT_H__ diff --git a/include_std/std/string.hpp b/include_std/std/string.hpp index 9bfab12e..f0dd0adc 100644 --- a/include_std/std/string.hpp +++ b/include_std/std/string.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_STRING_H__ diff --git a/include_std/std/unordered_map.hpp b/include_std/std/unordered_map.hpp index 345f6829..84ae6e74 100644 --- a/include_std/std/unordered_map.hpp +++ b/include_std/std/unordered_map.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_UNORDERED_MAP_H__ diff --git a/include_std/std/utility.hpp b/include_std/std/utility.hpp index 12814c47..518fdfef 100644 --- a/include_std/std/utility.hpp +++ b/include_std/std/utility.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STD_UTILITY_H__ diff --git a/include_std/stdarg.h b/include_std/stdarg.h index f079bb0e..46d7b050 100644 --- a/include_std/stdarg.h +++ b/include_std/stdarg.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STDARG_H__ diff --git a/include_std/stddef.h b/include_std/stddef.h index f346b21e..1f02863f 100644 --- a/include_std/stddef.h +++ b/include_std/stddef.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_STDDEF_STUB_H__ diff --git a/include_std/stdint.h b/include_std/stdint.h index e03e3bec..270d58c5 100644 --- a/include_std/stdint.h +++ b/include_std/stdint.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _STDINT_H diff --git a/include_std/stdio.h b/include_std/stdio.h index 732ac6dc..78829863 100644 --- a/include_std/stdio.h +++ b/include_std/stdio.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _STDIO_H diff --git a/include_std/stdlib.h b/include_std/stdlib.h index 3d95cab2..84cc7ad1 100644 --- a/include_std/stdlib.h +++ b/include_std/stdlib.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _STDLIB_H diff --git a/include_std/string b/include_std/string index 771861fb..928ea3fb 100644 --- a/include_std/string +++ b/include_std/string @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/string.h b/include_std/string.h index 2834743f..03306448 100644 --- a/include_std/string.h +++ b/include_std/string.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _STRING_H diff --git a/include_std/strings.h b/include_std/strings.h index ecb4e583..909d60f1 100644 --- a/include_std/strings.h +++ b/include_std/strings.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _STRINGS_H diff --git a/include_std/stropts.h b/include_std/stropts.h index bc6c48f7..b8b900e7 100644 --- a/include_std/stropts.h +++ b/include_std/stropts.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _STROPTS_H diff --git a/include_std/sys/stat.h b/include_std/sys/stat.h index 2ff2d38c..08f651d9 100644 --- a/include_std/sys/stat.h +++ b/include_std/sys/stat.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _SYS_STAT_H diff --git a/include_std/sys/time.h b/include_std/sys/time.h index eb48b447..9da4e6f4 100644 --- a/include_std/sys/time.h +++ b/include_std/sys/time.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _SYS_TIME_H diff --git a/include_std/sys/types.h b/include_std/sys/types.h index 447b6e11..10935064 100644 --- a/include_std/sys/types.h +++ b/include_std/sys/types.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _SYS_TYPES_H diff --git a/include_std/type_trails b/include_std/type_trails index 4a129efd..0def5633 100644 --- a/include_std/type_trails +++ b/include_std/type_trails @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/typeinfo b/include_std/typeinfo index 9bb9ee51..0cac6105 100644 --- a/include_std/typeinfo +++ b/include_std/typeinfo @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_TYPEINFO_H__ diff --git a/include_std/unistd.h b/include_std/unistd.h index fd50c1ec..0c048555 100644 --- a/include_std/unistd.h +++ b/include_std/unistd.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _UNISTD_H diff --git a/include_std/unwind.h b/include_std/unwind.h index d46b2f23..8c445409 100644 --- a/include_std/unwind.h +++ b/include_std/unwind.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_UNWIND_H__ diff --git a/include_std/utility b/include_std/utility index 9f2fbbba..f2b21e4e 100644 --- a/include_std/utility +++ b/include_std/utility @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once diff --git a/include_std/vector b/include_std/vector index 93da6160..105c0984 100644 --- a/include_std/vector +++ b/include_std/vector @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #pragma once @@ -105,10 +105,12 @@ namespace std if (Position == this->end()) { - warn("%#lx: Cannot erase element at end of vector", this); + warn("%#lx: Cannot erase element at end of vector (not found if std::find is used)", + this); return; } + assert(Position <= this->end()); assert(Position >= this->VectorBuffer); assert(Position < this->VectorBuffer + this->VectorSize); diff --git a/include_std/wchar.h b/include_std/wchar.h index 9fb14d0e..d22dab06 100644 --- a/include_std/wchar.h +++ b/include_std/wchar.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef _WCHAR_H diff --git a/kernel.cpp b/kernel.cpp new file mode 100644 index 00000000..c051a6e3 --- /dev/null +++ b/kernel.cpp @@ -0,0 +1,513 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "kernel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/smbios.hpp" +#include "tests/t.h" + +bool DebuggerIsAttached = false; +extern bool EnableProfiler; +NewLock(KernelLock); + +using vfs::Node; +using vfs::NodeType; + +__aligned(16) BootInfo bInfo{}; + +struct KernelConfig Config = { + .AllocatorType = Memory::liballoc11, + .SchedulerType = Multi, + .ModuleDirectory = {'/', 'm', 'o', 'd', 'u', 'l', 'e', 's', '\0'}, + .InitPath = {'/', 'b', 'i', 'n', '/', 'i', 'n', 'i', 't', '\0'}, + .UseLinuxSyscalls = false, + .InterruptsOnCrash = true, + .Cores = 0, + .IOAPICInterruptCore = 0, + .UnlockDeadLock = false, + .SIMD = false, + .BootAnimation = false, +}; + +Video::Display *Display = nullptr; +SymbolResolver::Symbols *KernelSymbolTable = nullptr; +Power::Power *PowerManager = nullptr; +Time::time *TimeManager = nullptr; +PCI::PCI *PCIManager = nullptr; +vfs::Virtual *fs = nullptr; +vfs::Node *DevFS = nullptr; +vfs::Node *MntFS = nullptr; +vfs::Node *ProcFS = nullptr; +vfs::Node *VarLogFS = nullptr; +Tasking::Task *TaskManager = nullptr; + +// For the Display class. Printing on first buffer as default. +int PutCharBufferIndex = 0; +EXTERNC void putchar(char c) +{ + if (Display) + Display->Print(c, PutCharBufferIndex); + else + UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(c); +} + +EXTERNC void KPrint(const char *Format, ...) +{ + SmartLock(KernelLock); + + if (TimeManager) + { + uint64_t Nanoseconds = TimeManager->GetNanosecondsSinceClassCreation(); + if (Nanoseconds != 0) + { +#if defined(a64) + printf("\eCCCCCC[\e00AEFF%lu.%07lu\eCCCCCC] ", + Nanoseconds / 10000000, Nanoseconds % 10000000); +#elif defined(a32) + printf("\eCCCCCC[\e00AEFF%llu.%07llu\eCCCCCC] ", + Nanoseconds / 10000000, Nanoseconds % 10000000); +#elif defined(aa64) + printf("\eCCCCCC[\e00AEFF%lu.%07lu\eCCCCCC] ", + Nanoseconds / 10000000, Nanoseconds % 10000000); +#endif + } + } + + va_list args; + va_start(args, Format); + vprintf(Format, args); + va_end(args); + + printf("\eCCCCCC\n"); + if (!Config.BootAnimation && Display) + Display->SetBuffer(0); +} + +EXTERNC NIF void Main() +{ + Display = new Video::Display(bInfo.Framebuffer[0]); + + KPrint("%s - %s [\e058C19%s\eFFFFFF]", + KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); + KPrint("CPU: \e058C19%s \e8822AA%s \e8888FF%s", + CPU::Hypervisor(), CPU::Vendor(), CPU::Name()); + + if (Display->GetFramebufferStruct().BitsPerPixel != 32) + KPrint("\eFF5500Framebuffer is not 32 bpp. This may cause issues."); + + debug("CPU: %s %s %s", + CPU::Hypervisor(), CPU::Vendor(), CPU::Name()); + + if (DebuggerIsAttached) + KPrint("\eFFA500Kernel debugger detected."); + +#if defined(a86) && defined(DEBUG) + uint8_t lpt1 = inb(0x378); + uint8_t lpt2 = inb(0x278); + uint8_t lpt3 = inb(0x3BC); + + uint8_t com1 = inb(0x3F8); + uint8_t com2 = inb(0x2F8); + uint8_t com3 = inb(0x3E8); + uint8_t com4 = inb(0x2E8); + + if (lpt1 != 0xFF) + KPrint("LPT1 is present."); + + if (lpt2 != 0xFF) + KPrint("LPT2 is present."); + + if (lpt3 != 0xFF) + KPrint("LPT3 is present."); + + if (com1 != 0xFF) + KPrint("COM1 is present."); + + if (com2 != 0xFF) + KPrint("COM2 is present."); + + if (com3 != 0xFF) + KPrint("COM3 is present."); + + if (com4 != 0xFF) + KPrint("COM4 is present."); + + KPrint("Display: %dx%d %d bpp \eFF0000R:%d %d \e00FF00G: %d %d \e0000FFB: %d %d", + Display->GetFramebufferStruct().Width, + Display->GetFramebufferStruct().Height, + Display->GetFramebufferStruct().BitsPerPixel, + Display->GetFramebufferStruct().RedMaskSize, + Display->GetFramebufferStruct().RedMaskShift, + Display->GetFramebufferStruct().GreenMaskSize, + Display->GetFramebufferStruct().GreenMaskShift, + Display->GetFramebufferStruct().BlueMaskSize, + Display->GetFramebufferStruct().BlueMaskShift); +#endif + + /**************************************************************************************/ + + KPrint("Reading Kernel Parameters"); + ParseConfig((char *)bInfo.Kernel.CommandLine, &Config); + + KPrint("Initializing CPU Features"); + CPU::InitializeFeatures(0); + + KPrint("Initializing GDT and IDT"); + Interrupts::Initialize(0); + + KPrint("Loading Kernel Symbols"); + KernelSymbolTable = + new SymbolResolver::Symbols((uintptr_t)bInfo.Kernel.FileBase); + + if (!KernelSymbolTable->SymTableExists) + KernelSymbolTable->AddSymbolInfoFromGRUB(bInfo.Kernel.Symbols.Num, + bInfo.Kernel.Symbols.EntSize, + bInfo.Kernel.Symbols.Shndx, + bInfo.Kernel.Symbols.Sections); + + if (Config.BootAnimation) + { + Display->CreateBuffer(0, 0, 1); + + Display->SetDoNotScroll(true, 1); + Video::ScreenBuffer *buf = Display->GetBuffer(1); + Video::FontInfo fi = Display->GetCurrentFont()->GetInfo(); + Display->SetBufferCursor(1, 0, buf->Height - fi.Height); + PutCharBufferIndex = 1; + printf("Fennix Operating System - %s [\e058C19%s\eFFFFFF]\n", + KERNEL_VERSION, GIT_COMMIT_SHORT); + Display->SetBuffer(1); + PutCharBufferIndex = 0; + } + + KPrint("Initializing Power Manager"); + PowerManager = new Power::Power; + + KPrint("Enabling Interrupts on Bootstrap Processor"); + Interrupts::Enable(0); + +#if defined(a86) + PowerManager->InitDSDT(); +#elif defined(aa64) +#endif + + KPrint("Initializing Timers"); + TimeManager = new Time::time; + TimeManager->FindTimers(PowerManager->GetACPI()); + + KPrint("Initializing PCI Manager"); + PCIManager = new PCI::PCI; + + foreach (auto Device in PCIManager->GetDevices()) + { + KPrint("PCI: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", + PCI::Descriptors::GetVendorName(Device.Header->VendorID), + PCI::Descriptors::GetDeviceName(Device.Header->VendorID, + Device.Header->DeviceID), + PCI::Descriptors::DeviceClasses[Device.Header->Class], + PCI::Descriptors::GetSubclassName(Device.Header->Class, + Device.Header->Subclass), + PCI::Descriptors::GetProgIFName(Device.Header->Class, + Device.Header->Subclass, + Device.Header->ProgIF)); + } + + KPrint("Initializing Bootstrap Processor Timer"); + Interrupts::InitializeTimer(0); + + KPrint("Initializing SMP"); + SMP::Initialize(PowerManager->GetMADT()); + + KPrint("Initializing Filesystem..."); + fs = new vfs::Virtual; + vfs::Node *root = fs->GetRootNode(); + if (root->Children.size() == 0) + fs->nRoot = new vfs::vfsRoot("/", fs); + + for (size_t i = 0; i < MAX_MODULES; i++) + { + if (!bInfo.Modules[i].Address) + continue; + + if (strcmp(bInfo.Modules[i].CommandLine, "initrd") == 0) + { + debug("Found initrd at %p", bInfo.Modules[i].Address); + static char initrd = 0; + if (!initrd++) + { + uintptr_t initrdAddress = (uintptr_t)bInfo.Modules[i].Address; + vfs::USTAR *ustar = new vfs::USTAR; + ustar->ReadArchive(initrdAddress, fs); + } + } + } + + if (!fs->PathExists("/dev")) + DevFS = new vfs::Node(fs->nRoot, "dev", vfs::DIRECTORY); + else + { + vfs::RefNode *dev = fs->Open("/dev"); + if (dev->node->Type != NodeType::DIRECTORY) + { + KPrint("\eE85230/dev is not a directory! Halting..."); + CPU::Stop(); + } + DevFS = dev->node; + delete dev; + } + + new vfs::NullDevice(); + new vfs::RandomDevice(); + new vfs::ZeroDevice(); + + if (!fs->PathExists("/mnt")) + MntFS = new vfs::Node(fs->nRoot, "mnt", vfs::DIRECTORY); + else + { + vfs::RefNode *mnt = fs->Open("/mnt"); + if (mnt->node->Type != NodeType::DIRECTORY) + { + KPrint("\eE85230/mnt is not a directory! Halting..."); + CPU::Stop(); + } + MntFS = mnt->node; + delete mnt; + } + + if (!fs->PathExists("/proc")) + ProcFS = new vfs::Node(fs->nRoot, "proc", vfs::DIRECTORY); + else + { + vfs::RefNode *proc = fs->Open("/proc", nullptr); + if (proc->node->Type != NodeType::DIRECTORY) + { + KPrint("\eE85230/proc is not a directory! Halting..."); + CPU::Stop(); + } + ProcFS = proc->node; + delete proc; + } + + if (!fs->PathExists("/var")) + { + vfs::Node *var = new vfs::Node(fs->nRoot, "var", vfs::DIRECTORY); + VarLogFS = new vfs::Node(var, "log", vfs::DIRECTORY); + } + else + { + vfs::RefNode *var = fs->Open("/var", nullptr); + if (var->node->Type != NodeType::DIRECTORY) + { + KPrint("\eE85230/var is not a directory! Halting..."); + CPU::Stop(); + } + VarLogFS = var->node; + delete var; + + if (!fs->PathExists("/var/log")) + VarLogFS = new vfs::Node(VarLogFS, "log", vfs::DIRECTORY); + else + { + vfs::RefNode *var_log = fs->Open("/var/log", nullptr); + if (var_log->node->Type != NodeType::DIRECTORY) + { + KPrint("\eE85230/var/log is not a directory! Halting..."); + CPU::Stop(); + } + VarLogFS = var_log->node; + delete var_log; + } + } + + KPrint("\e058C19################################"); + TaskManager = new Tasking::Task(Tasking::IP(KernelMainThread)); + CPU::Halt(true); +} + +typedef void (*CallPtr)(void); +extern CallPtr __init_array_start[0], __init_array_end[0]; +extern CallPtr __fini_array_start[0], __fini_array_end[0]; + +EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info) +{ + trace("Hello, World!"); + + if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) + { + debug("\n\n----------------------------------------\nDEBUGGER DETECTED\n----------------------------------------\n\n"); + DebuggerIsAttached = true; + } + + memcpy(&bInfo, Info, sizeof(BootInfo)); + debug("BootInfo structure is at %p", &bInfo); + + // https://wiki.osdev.org/Calling_Global_Constructors + trace("There are %d constructors to call", + __init_array_end - __init_array_start); + for (CallPtr *func = __init_array_start; func != __init_array_end; func++) + (*func)(); + +#ifdef a86 + if (!bInfo.SMBIOSPtr) + { + trace("SMBIOS was not provided by the bootloader. Trying to find it manually."); + for (uintptr_t i = 0xF0000; i < 0x100000; i += 16) + { + if (memcmp((void *)i, "_SM_", 4) == 0 || + memcmp((void *)i, "_SM3_", 5) == 0) + { + bInfo.SMBIOSPtr = (void *)i; + trace("Found SMBIOS at %#lx", i); + } + } + } + + if (!bInfo.RSDP) + { + trace("RSDP was not provided by the bootloader. Trying to find it manually."); + /* FIXME: Not always shifting by 4 will work. */ + uintptr_t EBDABase = (uintptr_t)mminw((void *)0x40E) << 4; + + for (uintptr_t ptr = EBDABase; + ptr < 0x100000; /* 1MB */ + ptr += 16) + { + if (unlikely(ptr == EBDABase + 0x400)) + { + trace("EBDA is full. Trying to find RSDP in the BIOS area."); + break; + } + + BootInfo::RSDPInfo *rsdp = (BootInfo::RSDPInfo *)ptr; + if (memcmp(rsdp->Signature, "RSD PTR ", 8) == 0) + { + bInfo.RSDP = (BootInfo::RSDPInfo *)rsdp; + trace("Found RSDP at %#lx", rsdp); + } + } + + for (uintptr_t ptr = 0xE0000; + ptr < 0x100000; /* 1MB */ + ptr += 16) + { + BootInfo::RSDPInfo *rsdp = (BootInfo::RSDPInfo *)ptr; + if (memcmp(rsdp->Signature, "RSD PTR ", 8) == 0) + { + bInfo.RSDP = (BootInfo::RSDPInfo *)rsdp; + trace("Found RSDP at %#lx", rsdp); + } + } + } +#endif + + InitializeMemoryManagement(); + + void *KernelStackAddress = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); + uintptr_t KernelStack = (uintptr_t)KernelStackAddress + STACK_SIZE - 0x10; + debug("Kernel stack: %#lx-%#lx", KernelStackAddress, KernelStack); +#if defined(a64) + asmv("mov %0, %%rsp" + : + : "r"(KernelStack) + : "memory"); + asmv("mov $0, %rbp"); +#elif defined(a32) + asmv("mov %0, %%esp" + : + : "r"(KernelStack) + : "memory"); + asmv("mov $0, %ebp"); +#elif defined(aa64) +#warning "Kernel stack is not set!" +#endif + +#ifdef DEBUG + /* I had to do this because KernelAllocator + * is a global constructor but we need + * memory management to be initialized first. + */ + TestMemoryAllocation(); + TestString(); + Test_std(); +#endif + EnableProfiler = true; + Main(); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" +extern "C" void __cxa_finalize(void *); +EXTERNC __no_stack_protector void BeforeShutdown(bool Reboot) +{ + /* TODO: Announce shutdown */ + + trace("\n\n\n#################### SYSTEM SHUTTING DOWN ####################\n\n"); + + KPrint("%s...", Reboot ? "Rebooting" : "Shutting down"); + + if (NIManager) + delete NIManager, NIManager = nullptr; + + if (DiskManager) + delete DiskManager, DiskManager = nullptr; + + if (ModuleManager) + delete ModuleManager, ModuleManager = nullptr; + + if (TaskManager && !TaskManager->IsPanic()) + { + TaskManager->SignalShutdown(); + delete TaskManager, TaskManager = nullptr; + } + + if (fs) + delete fs, fs = nullptr; + + if (TimeManager) + delete TimeManager, TimeManager = nullptr; + + // if (Display) + // delete Display, Display = nullptr; + // PowerManager should not be called + + // https://wiki.osdev.org/Calling_Global_Constructors + debug("Calling destructors..."); + for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++) + (*func)(); + __cxa_finalize(nullptr); + debug("Done."); +} +#pragma GCC diagnostic pop + +EXTERNC void TaskingPanic() +{ + if (TaskManager) + TaskManager->Panic(); +} diff --git a/kernel.h b/kernel.h index 05f57fc5..f82a4a23 100644 --- a/kernel.h +++ b/kernel.h @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_KERNEL_H__ @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -36,24 +36,25 @@ #endif extern struct BootInfo bInfo; +extern struct KernelConfig Config; extern bool DebuggerIsAttached; #ifdef __cplusplus extern Video::Display *Display; extern SymbolResolver::Symbols *KernelSymbolTable; extern Power::Power *PowerManager; -extern PCI::PCI *PCIManager; -extern KernelConfig Config; -extern Tasking::Task *TaskManager; extern Time::time *TimeManager; -extern VirtualFileSystem::Virtual *vfs; -extern Driver::Driver *DriverManager; +extern PCI::PCI *PCIManager; +extern vfs::Virtual *fs; +extern vfs::Node *DevFS; +extern vfs::Node *MntFS; +extern vfs::Node *ProcFS; +extern vfs::Node *VarLogFS; +extern Tasking::Task *TaskManager; + extern Disk::Manager *DiskManager; +extern Module::Module *ModuleManager; extern NetworkInterfaceManager::NetworkInterface *NIManager; -extern VirtualFileSystem::Node *DevFS; -extern VirtualFileSystem::Node *MntFS; -extern VirtualFileSystem::Node *ProcFS; -extern VirtualFileSystem::Node *VarLogFS; #endif // __cplusplus @@ -63,6 +64,9 @@ EXTERNC void Entry(struct BootInfo *Info); EXTERNC void BeforeShutdown(bool Reboot); EXTERNC void TaskingPanic(); +EXTERNC void BootLogoAnimationThread(); +EXTERNC void ExitLogoAnimationThread(); + EXTERNC void KernelMainThread(); EXTERNC void KernelShutdownThread(bool Reboot); EXTERNC void KST_Reboot(); diff --git a/KernelConfig.cpp b/kernel_config.cpp similarity index 75% rename from KernelConfig.cpp rename to kernel_config.cpp index 2d4fac77..b0206d42 100644 --- a/KernelConfig.cpp +++ b/kernel_config.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -70,7 +70,7 @@ static struct cag_option ConfigOptions[] = { .access_letters = "dD", .access_name = "drvdir", .value_name = "PATH", - .description = "Directory to load drivers from"}, + .description = "Directory to load modules from"}, {.identifier = 'i', .access_letters = "iI", @@ -147,7 +147,8 @@ void ParseConfig(char *ConfigString, KernelConfig *ModConfig) const char *value; cag_option_context context; - cag_option_prepare(&context, ConfigOptions, CAG_ARRAY_SIZE(ConfigOptions), argc, argv); + cag_option_prepare(&context, ConfigOptions, + CAG_ARRAY_SIZE(ConfigOptions), argc, argv); while (cag_option_fetch(&context)) { @@ -160,22 +161,22 @@ void ParseConfig(char *ConfigString, KernelConfig *ModConfig) if (strcmp(value, "xallocv1") == 0) { KPrint("\eAAFFAAUsing XallocV1 as memory allocator"); - ModConfig->AllocatorType = Memory::MemoryAllocatorType::XallocV1; + ModConfig->AllocatorType = Memory::XallocV1; } else if (strcmp(value, "xallocv2") == 0) { KPrint("\eAAFFAAUsing XallocV2 as memory allocator"); - ModConfig->AllocatorType = Memory::MemoryAllocatorType::XallocV2; + ModConfig->AllocatorType = Memory::XallocV2; } else if (strcmp(value, "liballoc11") == 0) { KPrint("\eAAFFAAUsing Liballoc11 as memory allocator"); - ModConfig->AllocatorType = Memory::MemoryAllocatorType::liballoc11; + ModConfig->AllocatorType = Memory::liballoc11; } else if (strcmp(value, "pages") == 0) { KPrint("\eAAFFAAUsing Pages as memory allocator"); - ModConfig->AllocatorType = Memory::MemoryAllocatorType::Pages; + ModConfig->AllocatorType = Memory::Pages; } break; } @@ -189,7 +190,8 @@ void ParseConfig(char *ConfigString, KernelConfig *ModConfig) case 'p': { value = cag_option_get_value(&context); - KPrint("\eAAFFAARedirecting I/O APIC interrupts to %s%s", atoi(value) ? "core " : "", atoi(value) ? value : "BSP"); + KPrint("\eAAFFAARedirecting I/O APIC interrupts to %s%s", + atoi(value) ? "core " : "", atoi(value) ? value : "BSP"); ModConfig->IOAPICInterruptCore = atoi(value); break; } @@ -216,8 +218,8 @@ void ParseConfig(char *ConfigString, KernelConfig *ModConfig) case 'd': { value = cag_option_get_value(&context); - strncpy(ModConfig->DriverDirectory, value, strlen(value)); - KPrint("\eAAFFAAUsing %s as driver directory", value); + strncpy(ModConfig->ModuleDirectory, value, strlen(value)); + KPrint("\eAAFFAAUsing %s as module directory", value); break; } case 'i': @@ -230,42 +232,51 @@ void ParseConfig(char *ConfigString, KernelConfig *ModConfig) case 'y': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? ModConfig->UseLinuxSyscalls = true : ModConfig->UseLinuxSyscalls = false; + strcmp(value, "true") == 0 + ? ModConfig->UseLinuxSyscalls = true + : ModConfig->UseLinuxSyscalls = false; KPrint("\eAAFFAAUse Linux syscalls by default: %s", value); break; } case 'o': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? ModConfig->InterruptsOnCrash = true : ModConfig->InterruptsOnCrash = false; + strcmp(value, "true") == 0 + ? ModConfig->InterruptsOnCrash = true + : ModConfig->InterruptsOnCrash = false; KPrint("\eAAFFAAInterrupts on crash: %s", value); break; } case 'l': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? ModConfig->UnlockDeadLock = true : ModConfig->UnlockDeadLock = false; + strcmp(value, "true") == 0 + ? ModConfig->UnlockDeadLock = true + : ModConfig->UnlockDeadLock = false; KPrint("\eAAFFAAUnlocking the deadlock after 10 retries"); break; } case 's': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? ModConfig->SIMD = true : ModConfig->SIMD = false; + strcmp(value, "true") == 0 ? ModConfig->SIMD = true + : ModConfig->SIMD = false; KPrint("\eAAFFAASingle Instruction, Multiple Data (SIMD): %s", value); break; } case 'b': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? ModConfig->BootAnimation = true : ModConfig->BootAnimation = false; + strcmp(value, "true") == 0 ? ModConfig->BootAnimation = true + : ModConfig->BootAnimation = false; KPrint("\eAAFFAABoot animation: %s", value); break; } case 'h': { KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration."); - cag_option_print(ConfigOptions, CAG_ARRAY_SIZE(ConfigOptions), nullptr); + cag_option_print(ConfigOptions, CAG_ARRAY_SIZE(ConfigOptions), + nullptr); KPrint("\eFF2200System Halted."); CPU::Stop(); } diff --git a/kernel_thread.cpp b/kernel_thread.cpp new file mode 100644 index 00000000..b70eb8d0 --- /dev/null +++ b/kernel_thread.cpp @@ -0,0 +1,192 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "kernel.h" +#ifdef DEBUG +#include "tests/t.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mapi.hpp" +#include "Fex.hpp" + +using vfs::Node; +using vfs::NodeType; + +Disk::Manager *DiskManager = nullptr; +Module::Module *ModuleManager = nullptr; +NetworkInterfaceManager::NetworkInterface *NIManager = nullptr; + +int SpawnInit() +{ + const char *envp[5] = { + "PATH=/bin:/usr/bin", + "TERM=tty", + "HOME=/root", + "USER=root", + nullptr}; + + const char *argv[4] = { + Config.InitPath, + "--init", + "--critical", + nullptr}; + + return Execute::Spawn(Config.InitPath, argv, envp, + nullptr, + Tasking::TaskCompatibility::Native, + true); +} + +void CleanupProcessesThreadWrapper() +{ + TaskManager->CleanupProcessesThread(); +} + +void KernelMainThread() +{ + Tasking::TCB *clnThd = + TaskManager->CreateThread(thisProcess, + Tasking::IP(CleanupProcessesThreadWrapper)); + clnThd->SetPriority(Tasking::Idle); + TaskManager->SetCleanupThread(clnThd); + thisThread->SetPriority(Tasking::Critical); + + Tasking::TCB *blaThread = nullptr; + + if (Config.BootAnimation) + { + blaThread = + TaskManager->CreateThread(thisProcess, + Tasking::IP(BootLogoAnimationThread)); + blaThread->Rename("Logo Animation"); + } + +#ifdef DEBUG + // TaskManager->CreateThread(thisProcess, Tasking::IP(tasking_test_fb)); + // TaskManager->CreateThread(thisProcess, Tasking::IP(tasking_test_mutex)); + // ilp; + TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr)); + TaskManager->CreateThread(thisProcess, Tasking::IP(lsof)); + TreeFS(fs->GetRootNode(), 0); +#endif + + KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", + __DATE__, __TIME__, CPP_LANGUAGE_STANDARD); + KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus); + + if (IsVirtualizedEnvironment()) + KPrint("Running in a virtualized environment"); + + KPrint("Initializing Disk Manager..."); + DiskManager = new Disk::Manager; + + KPrint("Loading Modules..."); + ModuleManager = new Module::Module; + ModuleManager->LoadModules(); + + KPrint("Fetching Disks..."); + if (ModuleManager->GetModules().size() > 0) + { + foreach (auto mod in ModuleManager->GetModules()) + if (((FexExtended *)mod.ExtendedHeaderAddress)->Module.Type == FexModuleType::FexModuleType_Storage) + DiskManager->FetchDisks(mod.modUniqueID); + } + else + KPrint("\eE85230No disk modules found! Cannot fetch disks!"); + + KPrint("Initializing Network Interface Manager..."); + NIManager = new NetworkInterfaceManager::NetworkInterface; + KPrint("Starting Network Interface Manager..."); + NIManager->StartService(); + + KPrint("Setting up userspace"); + int ExitCode = -1; + Tasking::TCB *initThread = nullptr; + int tid = SpawnInit(); + if (tid < 0) + { + KPrint("\eE85230Failed to start %s! Code: %d", Config.InitPath, tid); + goto Exit; + } + + KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath); + thisThread->SetPriority(Tasking::Idle); + + initThread = TaskManager->GetThreadByID(tid); + initThread->KeepInMemory = true; + TaskManager->WaitForThread(initThread); + ExitCode = initThread->GetExitCode(); +Exit: + if (ExitCode == 0) + { + KPrint("\eFF7900%s process exited with code %d and it didn't invoked the shutdown function.", + Config.InitPath, ExitCode); + KPrint("System Halted"); + CPU::Halt(true); + } + + KPrint("\eE85230Userspace process exited with code %d (%#x)", + ExitCode, ExitCode < 0 ? -ExitCode : ExitCode); + + KPrint("Dropping to kernel shell..."); + TaskManager->Sleep(1000); + TaskManager->WaitForThread(blaThread); + TaskManager->CreateThread(thisProcess, + Tasking::IP(KShellThread)) + ->Rename("Kernel Shell"); + + if (initThread) + initThread->KeepInMemory = false; + CPU::Halt(true); +} + +NewLock(ShutdownLock); +void __no_stack_protector KernelShutdownThread(bool Reboot) +{ + SmartLock(ShutdownLock); + debug("KernelShutdownThread(%s)", Reboot ? "true" : "false"); + if (Config.BootAnimation && TaskManager) + { + Tasking::TCB *elaThread = + TaskManager->CreateThread(thisProcess, + Tasking::IP(ExitLogoAnimationThread)); + elaThread->Rename("Logo Animation"); + TaskManager->WaitForThread(elaThread); + } + + BeforeShutdown(Reboot); + + trace("%s...", Reboot ? "Rebooting" : "Shutting down"); + if (Reboot) + PowerManager->Reboot(); + else + PowerManager->Shutdown(); + CPU::Stop(); +} + +void KST_Reboot() { KernelShutdownThread(true); } +void KST_Shutdown() { KernelShutdownThread(false); } diff --git a/KernelShell/cmds.hpp b/kshell/cmds.hpp similarity index 51% rename from KernelShell/cmds.hpp rename to kshell/cmds.hpp index 9ec79d71..d1200228 100644 --- a/KernelShell/cmds.hpp +++ b/kshell/cmds.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_SHELL_CMDS_H__ diff --git a/kshell/commands/cat.cpp b/kshell/commands/cat.cpp new file mode 100644 index 00000000..eefeb735 --- /dev/null +++ b/kshell/commands/cat.cpp @@ -0,0 +1,54 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include + +#include "../../kernel.h" + +using namespace vfs; + +void cmd_cat(const char *args) +{ + if (args[0] == '\0') + return; + + Node *thisNode = fs->GetNodeFromPath(args, thisProcess->CurrentWorkingDirectory); + if (thisNode == nullptr) + { + printf("cat: %s: No such file or directory\n", args); + return; + } + + if (thisNode->Type != NodeType::FILE && + thisNode->Type != NodeType::CHARDEVICE) + { + printf("cat: %s: Not a file\n", args); + return; + } + + int fd = fopen(thisNode->FullPath, "r"); + struct stat st; + fstat(fd, &st); + + char *buffer = new char[st.st_size + 1]; + fread(fd, buffer, st.st_size); + printf("%s\n", buffer); + delete[] buffer; + fclose(fd); +} diff --git a/kshell/commands/cd.cpp b/kshell/commands/cd.cpp new file mode 100644 index 00000000..f8d2668d --- /dev/null +++ b/kshell/commands/cd.cpp @@ -0,0 +1,46 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include + +#include "../../kernel.h" + +using namespace vfs; + +void cmd_cd(const char *args) +{ + if (args[0] == '\0') + return; + + Node *thisNode = fs->GetNodeFromPath(args, thisProcess->CurrentWorkingDirectory); + + if (thisNode == nullptr) + { + printf("cd: %s: No such file or directory\n", args); + return; + } + + if (thisNode->Type != NodeType::DIRECTORY) + { + printf("cd: %s: Not a directory\n", args); + return; + } + + thisProcess->CurrentWorkingDirectory = thisNode; +} diff --git a/kshell/commands/echo.cpp b/kshell/commands/echo.cpp new file mode 100644 index 00000000..f4aa2e90 --- /dev/null +++ b/kshell/commands/echo.cpp @@ -0,0 +1,25 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include "../../kernel.h" + +void cmd_echo(const char *args) +{ + printf("%s\n", args); +} diff --git a/kshell/commands/exit.cpp b/kshell/commands/exit.cpp new file mode 100644 index 00000000..20dcb9d9 --- /dev/null +++ b/kshell/commands/exit.cpp @@ -0,0 +1,33 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_exit(const char *) +{ + KernelShutdownThread(false); + // TaskManager->KillThread(thisThread, KILL_SUCCESS); + CPU::Halt(true); +} diff --git a/kshell/commands/kill.cpp b/kshell/commands/kill.cpp new file mode 100644 index 00000000..76879a76 --- /dev/null +++ b/kshell/commands/kill.cpp @@ -0,0 +1,39 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_kill(const char *args) +{ + PID pid = atoi(args); + PCB *pcb = TaskManager->GetProcessByID(pid); + + if (pcb == nullptr) + { + printf("No process with PID %d\n", pid); + return; + } + TaskManager->KillProcess(pcb, KILL_BY_OTHER_PROCESS); +} diff --git a/kshell/commands/killall.cpp b/kshell/commands/killall.cpp new file mode 100644 index 00000000..93dd8a29 --- /dev/null +++ b/kshell/commands/killall.cpp @@ -0,0 +1,37 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_killall(const char *args) +{ + foreach (auto Proc in TaskManager->GetProcessList()) + { + if (strcmp(Proc->Name, args) == 0) + { + TaskManager->KillProcess(Proc, KILL_BY_OTHER_PROCESS); + } + } +} diff --git a/kshell/commands/ls.cpp b/kshell/commands/ls.cpp new file mode 100644 index 00000000..38c3d140 --- /dev/null +++ b/kshell/commands/ls.cpp @@ -0,0 +1,57 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include + +#include "../../kernel.h" + +using namespace vfs; + +void cmd_ls(const char *args) +{ + if (args[0] == '\0') + { + Node *rootNode = thisProcess->CurrentWorkingDirectory; + + if (rootNode == nullptr) + rootNode = fs->GetRootNode()->Children[0]; + + foreach (auto var in rootNode->Children) + printf("%s\n", var->Name); + } + else + { + Node *thisNode = fs->GetNodeFromPath(args, thisProcess->CurrentWorkingDirectory); + + if (thisNode == nullptr) + { + printf("ls: %s: No such file or directory\n", args); + return; + } + + if (thisNode->Type != NodeType::DIRECTORY) + { + printf("%s\n", thisNode->Name); + return; + } + + foreach (auto var in thisNode->Children) + printf("%s\n", var->Name); + } +} diff --git a/kshell/commands/lsof.cpp b/kshell/commands/lsof.cpp new file mode 100644 index 00000000..92f00174 --- /dev/null +++ b/kshell/commands/lsof.cpp @@ -0,0 +1,36 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include "../../kernel.h" + +void cmd_lsof(const char *) +{ + printf("PROCESS FD NAME\n"); + foreach (auto Proc in TaskManager->GetProcessList()) + { + if (!Proc) + continue; + + std::vector fds_array = + Proc->FileDescriptors->GetFileDescriptors(); + foreach (auto fd in fds_array) + printf("%s %d: %s\n", Proc->Name, fd.Descriptor, + fd.Handle->node->FullPath); + } +} diff --git a/kshell/commands/lspci.cpp b/kshell/commands/lspci.cpp new file mode 100644 index 00000000..ddf66e97 --- /dev/null +++ b/kshell/commands/lspci.cpp @@ -0,0 +1,40 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include + +#include "../../kernel.h" + +using namespace vfs; + +void cmd_lspci(const char *) +{ + foreach (auto Device in PCIManager->GetDevices()) + { + printf("%02x:%02x.%d: %s: %s %s\n", + Device.Bus, + Device.Device, + Device.Function, + PCI::Descriptors::GetSubclassName(Device.Header->Class, + Device.Header->Subclass), + PCI::Descriptors::GetVendorName(Device.Header->VendorID), + PCI::Descriptors::GetDeviceName(Device.Header->VendorID, + Device.Header->DeviceID)); + } +} diff --git a/KernelShell/Commands/mem.cpp b/kshell/commands/mem.cpp similarity index 64% rename from KernelShell/Commands/mem.cpp rename to kshell/commands/mem.cpp index b7c73b7a..1b2e51a1 100644 --- a/KernelShell/Commands/mem.cpp +++ b/kshell/commands/mem.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../cmds.hpp" @@ -22,7 +22,7 @@ #include "../../kernel.h" -using namespace VirtualFileSystem; +using namespace vfs; using namespace Tasking; void cmd_mem(const char *) diff --git a/kshell/commands/ps.cpp b/kshell/commands/ps.cpp new file mode 100644 index 00000000..fcc2ac1a --- /dev/null +++ b/kshell/commands/ps.cpp @@ -0,0 +1,33 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_ps(const char *) +{ + printf("PID Name\n"); + foreach (auto p in TaskManager->GetProcessList()) + printf("%d %s\n", p->ID, p->Name); +} diff --git a/kshell/commands/reboot.cpp b/kshell/commands/reboot.cpp new file mode 100644 index 00000000..a9da5456 --- /dev/null +++ b/kshell/commands/reboot.cpp @@ -0,0 +1,32 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_reboot(const char *) +{ + KernelShutdownThread(true); + CPU::Halt(true); +} diff --git a/kshell/commands/shutdown.cpp b/kshell/commands/shutdown.cpp new file mode 100644 index 00000000..0d3acea6 --- /dev/null +++ b/kshell/commands/shutdown.cpp @@ -0,0 +1,32 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_shutdown(const char *) +{ + KernelShutdownThread(false); + CPU::Halt(true); +} diff --git a/kshell/commands/top.cpp b/kshell/commands/top.cpp new file mode 100644 index 00000000..4076e441 --- /dev/null +++ b/kshell/commands/top.cpp @@ -0,0 +1,60 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; +using namespace Tasking; + +void cmd_top(const char *) +{ + printf("\e9400A1PID \e9CA100Name \e00A15BState \eCCCCCCPriority Memory Usage CPU Usage\n"); + foreach (auto Proc in TaskManager->GetProcessList()) + { +#if defined(a64) + printf("\e9400A1%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %ld KiB %ld\n", + Proc->ID, Proc->Name, Proc->State == Running ? "Running" : "Stopped", + Proc->Info.Priority, TO_KiB(Proc->GetSize()), + Proc->Info.UserTime + Proc->Info.KernelTime); +#elif defined(a32) + printf("\e9400A1%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %lld KiB %lld\n", + Proc->ID, Proc->Name, Proc->State == Running ? "Running" : "Stopped", + Proc->Info.Priority, TO_KiB(Proc->GetSize()), + Proc->Info.UserTime + Proc->Info.KernelTime); +#endif + + foreach (auto Thrd in Proc->Threads) + { +#if defined(a64) + printf(" \eA80011%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %ld KiB %ld\n", + Thrd->ID, Thrd->Name, Thrd->State == Running ? "Running" : "Stopped", + Thrd->Info.Priority, TO_KiB(Thrd->GetSize()), + Thrd->Info.UserTime + Thrd->Info.KernelTime); +#elif defined(a32) + printf(" \eA80011%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %lld KiB %lld\n", + Thrd->ID, Thrd->Name, Thrd->State == Running ? "Running" : "Stopped", + Thrd->Info.Priority, TO_KiB(Thrd->GetSize()), + Thrd->Info.UserTime + Thrd->Info.KernelTime); +#endif + } + } +} diff --git a/KernelShell/Commands/uname.cpp b/kshell/commands/uname.cpp similarity index 51% rename from KernelShell/Commands/uname.cpp rename to kshell/commands/uname.cpp index 087eba94..e4e59a75 100644 --- a/KernelShell/Commands/uname.cpp +++ b/kshell/commands/uname.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../cmds.hpp" @@ -21,7 +21,7 @@ #include "../../kernel.h" -using namespace VirtualFileSystem; +using namespace vfs; void cmd_uname(const char *args) { diff --git a/KernelShell/Commands/uptime.cpp b/kshell/commands/uptime.cpp similarity index 53% rename from KernelShell/Commands/uptime.cpp rename to kshell/commands/uptime.cpp index 3aab5b5b..ff85b37d 100644 --- a/KernelShell/Commands/uptime.cpp +++ b/kshell/commands/uptime.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "../cmds.hpp" @@ -21,7 +21,7 @@ #include "../../kernel.h" -using namespace VirtualFileSystem; +using namespace vfs; void cmd_uptime(const char *) { diff --git a/kshell/commands/whoami.cpp b/kshell/commands/whoami.cpp new file mode 100644 index 00000000..ba2a2ce2 --- /dev/null +++ b/kshell/commands/whoami.cpp @@ -0,0 +1,29 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include + +#include "../../kernel.h" + +using namespace vfs; + +void cmd_whoami(const char *) +{ + printf("kernel\n"); +} diff --git a/KernelShell/Shell.cpp b/kshell/shell.cpp similarity index 85% rename from KernelShell/Shell.cpp rename to kshell/shell.cpp index 675142e5..00739034 100644 --- a/KernelShell/Shell.cpp +++ b/kshell/shell.cpp @@ -1,31 +1,31 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include #include -#include +#include #include #include -#include "../Modules/PersonalSystem2/keyboard.hpp" +#include "../modules/PersonalSystem2/keyboard.hpp" #include "../kernel.h" #include "../Fex.hpp" -#include "../DAPI.hpp" +#include "../mapi.hpp" #include "cmds.hpp" using namespace PS2Keyboard; @@ -147,17 +147,17 @@ void StartKernelShell() thisThread->SetPriority(Tasking::TaskPriority::High); Display->SetBuffer(0); - Driver::DriverFile KeyboardModule; - if (likely(DriverManager->GetDrivers().size() > 0)) + Module::ModuleFile KeyboardModule; + if (likely(ModuleManager->GetModules().size() > 0)) { - foreach (auto Driver in DriverManager->GetDrivers()) + foreach (auto Module in ModuleManager->GetModules()) { - if (((FexExtended *)Driver.ExtendedHeaderAddress)->Driver.Type == FexDriverType::FexDriverType_Input && - ((FexExtended *)Driver.ExtendedHeaderAddress)->Driver.TypeFlags & FexDriverInputTypes::FexDriverInputTypes_Keyboard) + if (((FexExtended *)Module.ExtendedHeaderAddress)->Module.Type == FexModuleType::FexModuleType_Input && + ((FexExtended *)Module.ExtendedHeaderAddress)->Module.TypeFlags & FexDriverInputTypes::FexDriverInputTypes_Keyboard) { - KeyboardModule = Driver; + KeyboardModule = Module; printf("Using driver \eCA21F6%s\eCCCCCC for keyboard input.\n", - ((FexExtended *)Driver.ExtendedHeaderAddress)->Driver.Name); + ((FexExtended *)Module.ExtendedHeaderAddress)->Module.Name); break; } } @@ -175,21 +175,21 @@ void StartKernelShell() size_t BackspaceCount = 0; Buffer.clear(); - VirtualFileSystem::Node *cwd = thisProcess->CurrentWorkingDirectory; + vfs::Node *cwd = thisProcess->CurrentWorkingDirectory; if (!cwd) - cwd = vfs->GetNodeFromPath("/"); + cwd = fs->GetNodeFromPath("/"); printf("\e34C6EB%s@%s:%s$ \eCCCCCC", "kernel", "fennix", - cwd->FileSystem->GetPathFromNode(cwd).c_str()); + cwd->FullPath); Display->SetBuffer(0); while (true) { KernelCallback callback{}; callback.Reason = PollWaitReason; - DriverManager->IOCB(KeyboardModule.DriverUID, &callback); + ModuleManager->IOCB(KeyboardModule.modUniqueID, &callback); char c = GetLetterFromScanCode(callback.InputCallback.Keyboard.Key); switch (callback.InputCallback.Keyboard.Key) diff --git a/library/bitmap.cpp b/library/bitmap.cpp new file mode 100644 index 00000000..aa3e7e9a --- /dev/null +++ b/library/bitmap.cpp @@ -0,0 +1,51 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +bool Bitmap::Get(uint64_t index) +{ + if (index > Size * 8) + return false; + + uint64_t byteIndex = index / 8; + uint8_t bitIndex = index % 8; + uint8_t bitIndexer = 0b10000000 >> bitIndex; + + if ((Buffer[byteIndex] & bitIndexer) > 0) + return true; + + return false; +} + +bool Bitmap::Set(uint64_t index, bool value) +{ + if (index > Size * 8) + return false; + + uint64_t byteIndex = index / 8; + uint8_t bitIndex = index % 8; + uint8_t bitIndexer = 0b10000000 >> bitIndex; + + Buffer[byteIndex] &= ~bitIndexer; + if (value) + Buffer[byteIndex] |= bitIndexer; + + return true; +} + +bool Bitmap::operator[](uint64_t index) { return this->Get(index); } diff --git a/Library/cargs.c b/library/cargs.c similarity index 100% rename from Library/cargs.c rename to library/cargs.c diff --git a/Library/Convert.cpp b/library/convert.cpp similarity index 96% rename from Library/Convert.cpp rename to library/convert.cpp index f4e5ade5..9fd969b0 100644 --- a/Library/Convert.cpp +++ b/library/convert.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Library/CyclicRedundancyCheck32.c b/library/crc32.c similarity index 85% rename from Library/CyclicRedundancyCheck32.c rename to library/crc32.c index 4deb16a5..1ca48212 100644 --- a/Library/CyclicRedundancyCheck32.c +++ b/library/crc32.c @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Library/cwalk.c b/library/cwalk.c similarity index 99% rename from Library/cwalk.c rename to library/cwalk.c index 2e1755c0..435f1ef0 100644 --- a/Library/cwalk.c +++ b/library/cwalk.c @@ -33,12 +33,17 @@ SOFTWARE. * We try to default to a different path style depending on the operating * system. So this should detect whether we should use windows or unix paths. */ +/* #if defined(WIN32) || defined(_WIN32) || \ defined(__WIN32) && !defined(__CYGWIN__) static enum cwk_path_style path_style = CWK_STYLE_WINDOWS; #else static enum cwk_path_style path_style = CWK_STYLE_UNIX; #endif +*/ + +extern enum cwk_path_style *__cwalk_path_style(void); +#define path_style (*__cwalk_path_style()) /** * This is a list of separators used in different styles. Windows can read diff --git a/library/cwalk_path_style.cpp b/library/cwalk_path_style.cpp new file mode 100644 index 00000000..a4b50717 --- /dev/null +++ b/library/cwalk_path_style.cpp @@ -0,0 +1,30 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +#include "../kernel.h" + +__aligned(16) static cwk_path_style path_style = CWK_STYLE_UNIX; + +EXTERNC cwk_path_style *__cwalk_path_style(void) +{ + if (unlikely(!TaskManager || !thisThread)) + return &path_style; + return &thisThread->Info.PathStyle; +} diff --git a/Library/dumper.cpp b/library/dumper.cpp similarity index 74% rename from Library/dumper.cpp rename to library/dumper.cpp index b2b0c62d..643e3887 100644 --- a/Library/dumper.cpp +++ b/library/dumper.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "dumper.hpp" diff --git a/Library/libstdc++/class_type_info.cpp b/library/libstdc++/class_type_info.cpp similarity index 75% rename from Library/libstdc++/class_type_info.cpp rename to library/libstdc++/class_type_info.cpp index 4e909e1c..d5ebde1a 100644 --- a/Library/libstdc++/class_type_info.cpp +++ b/library/libstdc++/class_type_info.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Library/libstdc++/cxxabi.cpp b/library/libstdc++/cxxabi.cpp similarity index 90% rename from Library/libstdc++/cxxabi.cpp rename to library/libstdc++/cxxabi.cpp index 942dd8d1..1417da52 100644 --- a/Library/libstdc++/cxxabi.cpp +++ b/library/libstdc++/cxxabi.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/library/libstdc++/fundamental_type_info.cpp b/library/libstdc++/fundamental_type_info.cpp new file mode 100644 index 00000000..aaa81077 --- /dev/null +++ b/library/libstdc++/fundamental_type_info.cpp @@ -0,0 +1,23 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +namespace __cxxabiv1 +{ + __fundamental_type_info::~__fundamental_type_info() {} +} diff --git a/Library/libstdc++/pbase_type_info.cpp b/library/libstdc++/pbase_type_info.cpp similarity index 72% rename from Library/libstdc++/pbase_type_info.cpp rename to library/libstdc++/pbase_type_info.cpp index c7658f39..a4e40a06 100644 --- a/Library/libstdc++/pbase_type_info.cpp +++ b/library/libstdc++/pbase_type_info.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/library/libstdc++/pointer_type_info.cpp b/library/libstdc++/pointer_type_info.cpp new file mode 100644 index 00000000..46d5b2fd --- /dev/null +++ b/library/libstdc++/pointer_type_info.cpp @@ -0,0 +1,45 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +namespace __cxxabiv1 +{ + __pointer_type_info::~__pointer_type_info() {} + + bool __pointer_type_info::__is_pointer_p() const { return true; } + + bool __pointer_type_info::__pointer_catch(const __pbase_type_info *ThrownType, + void **ThrowObject, + unsigned Outer) const + { +#ifndef __GXX_RTTI + UNUSED(ThrownType); + UNUSED(ThrowObject); + UNUSED(Outer); + return false; +#else + if (Outer < 2 && *this->Pointee == typeid(void)) + return !ThrownType->Pointee->__is_function_p(); + + return __pbase_type_info::__pointer_catch(ThrownType, + ThrowObject, + Outer); +#endif + } + +} diff --git a/Library/libstdc++/si_class_type_info.cpp b/library/libstdc++/si_class_type_info.cpp similarity index 76% rename from Library/libstdc++/si_class_type_info.cpp rename to library/libstdc++/si_class_type_info.cpp index d6048c70..cb37dfd0 100644 --- a/Library/libstdc++/si_class_type_info.cpp +++ b/library/libstdc++/si_class_type_info.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/library/libstdc++/unwind.cpp b/library/libstdc++/unwind.cpp new file mode 100644 index 00000000..30e2a5be --- /dev/null +++ b/library/libstdc++/unwind.cpp @@ -0,0 +1,41 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include +#include +#include + +#include "../../kernel.h" + +using namespace __cxxabiv1; + +#if (1) /* Stubs if libgcc is not present */ +extern "C" _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *Exception) +{ + fixme("_Unwind_RaiseException( %p ) called.", Exception); + error("Unhandled exception."); + return _URC_FATAL_PHASE1_ERROR; + // return _URC_NO_REASON; +} + +extern "C" void _Unwind_Resume(struct _Unwind_Exception *Exception) +{ + fixme("_Unwind_Resume( %p ) called.", Exception); +} +#endif diff --git a/Library/md5.c b/library/md5.c similarity index 100% rename from Library/md5.c rename to library/md5.c diff --git a/Library/MemOp.c b/library/memop.c similarity index 100% rename from Library/MemOp.c rename to library/memop.c diff --git a/Library/printf.c b/library/printf.c similarity index 100% rename from Library/printf.c rename to library/printf.c diff --git a/Library/MemoryCopySIMD.cpp b/library/simd_memcpy.cpp similarity index 86% rename from Library/MemoryCopySIMD.cpp rename to library/simd_memcpy.cpp index 3b42b802..af040391 100644 --- a/Library/MemoryCopySIMD.cpp +++ b/library/simd_memcpy.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Library/MemoryMoveSIMD.cpp b/library/simd_memmove.cpp similarity index 59% rename from Library/MemoryMoveSIMD.cpp rename to library/simd_memmove.cpp index 5a11b643..36e71983 100644 --- a/Library/MemoryMoveSIMD.cpp +++ b/library/simd_memmove.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Library/MemorySetSIMD.cpp b/library/simd_memset.cpp similarity index 67% rename from Library/MemorySetSIMD.cpp rename to library/simd_memset.cpp index d43b394a..8b71e76d 100644 --- a/Library/MemorySetSIMD.cpp +++ b/library/simd_memset.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/library/std/errno.cpp b/library/std/errno.cpp new file mode 100644 index 00000000..be514bff --- /dev/null +++ b/library/std/errno.cpp @@ -0,0 +1,33 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include + +#include "../../kernel.h" + +__aligned(16) static int errno_value = 0; + +int *__errno_location(void) +{ + if (unlikely(!TaskManager || !thisThread)) + return &errno_value; + return &thisThread->ErrorNumber; +} diff --git a/Library/std/mutex.cpp b/library/std/mutex.cpp similarity index 63% rename from Library/std/mutex.cpp rename to library/std/mutex.cpp index 37681da0..1baff3b8 100644 --- a/Library/std/mutex.cpp +++ b/library/std/mutex.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/library/std/typeinfo.cpp b/library/std/typeinfo.cpp new file mode 100644 index 00000000..a0eb245a --- /dev/null +++ b/library/std/typeinfo.cpp @@ -0,0 +1,44 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +namespace std +{ + type_info::~type_info() {} + + bool type_info::__do_catch(const type_info *ThrowType, + void **ThrowObject, + unsigned Outer) const + { + stub; + UNUSED(ThrowType); + UNUSED(ThrowObject); + UNUSED(Outer); + return false; + } + + bool type_info::__do_upcast(const __cxxabiv1::__class_type_info *Target, + void **ObjectPointer) const + { + stub; + UNUSED(Target); + UNUSED(ObjectPointer); + return false; + } +} diff --git a/Library/targp.c b/library/targp.c similarity index 50% rename from Library/targp.c rename to library/targp.c index 80639972..b39d8ee8 100644 --- a/Library/targp.c +++ b/library/targp.c @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/DAPI.hpp b/mapi.hpp similarity index 72% rename from DAPI.hpp rename to mapi.hpp index 642a738c..d8f87b63 100644 --- a/DAPI.hpp +++ b/mapi.hpp @@ -1,50 +1,50 @@ /* - BSD 3-Clause License + BSD 3-Clause License - Copyright (c) 2023, EnderIce2 - All rights reserved. + Copyright (c) 2023, EnderIce2 + All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __FENNIX_DRIVER_API_H__ -#define __FENNIX_DRIVER_API_H__ +#ifndef __FENNIX_MODULE_API_H__ +#define __FENNIX_MODULE_API_H__ /** - * The driver API is a set of functions that the kernel provides to the drivers. + * The module API is a set of functions that the kernel provides to the drivers. * - * - The driver is responsible for the memory management. - * - The kernel will NOT free any memory allocated by the driver. On @see StopReason the driver must free all the memory it allocated and disable the hardware it uses. - * - The driver image will be freed after the driver is unloaded. + * - The module is responsible for the memory management. + * - The kernel will NOT free any memory allocated by the module. On @see StopReason the module must free all the memory it allocated and disable the hardware it uses. + * - The module image will be freed after the module is unloaded. * - The kernel will unbind the interrupt handlers and the process handlers. - * - Kernel API will be freed after the driver is unloaded. + * - Kernel API will be freed after the module is unloaded. * */ -enum DriverReturnCode +enum ModuleReturnCode { ERROR, OK, @@ -64,7 +64,7 @@ enum DriverReturnCode KERNEL_API_VERSION_NOT_SUPPORTED, }; -enum DriverBindType +enum ModuleBindType { BIND_NULL, BIND_INTERRUPT, @@ -85,7 +85,7 @@ struct KernelAPI struct KAPIInfo { __UINT64_TYPE__ Offset; - __UINT32_TYPE__ DriverUID; + __UINT32_TYPE__ modUniqueID; char KernelDebug; } Info; @@ -105,7 +105,7 @@ struct KernelAPI struct KAPIUtilities { - void (*DebugPrint)(char *String, __UINT64_TYPE__ DriverUID); + void (*DebugPrint)(char *String, __UINT64_TYPE__ modUniqueID); void (*DisplayPrint)(char *Value); void *(*memcpy)(void *Destination, void *Source, __UINT64_TYPE__ Size); void *(*memset)(void *Destination, int Value, __UINT64_TYPE__ Size); @@ -113,13 +113,13 @@ struct KernelAPI int (*sprintf)(char *Buffer, const char *Format, ...); } Util; - struct KAPIDriverTalk + struct KAPIModuleTalk { /** Connects to the network manager */ struct { - void (*SendPacket)(__UINT32_TYPE__ DriverID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size); - void (*ReceivePacket)(__UINT32_TYPE__ DriverID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size); + void (*SendPacket)(__UINT32_TYPE__ ModuleID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size); + void (*ReceivePacket)(__UINT32_TYPE__ ModuleID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size); } Network; /** Connects to the disk manager */ @@ -127,8 +127,8 @@ struct KernelAPI { struct { - void (*ReadSector)(__UINT32_TYPE__ DriverID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port); - void (*WriteSector)(__UINT32_TYPE__ DriverID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port); + void (*ReadSector)(__UINT32_TYPE__ ModuleID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port); + void (*WriteSector)(__UINT32_TYPE__ ModuleID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port); } AHCI; } Disk; } Command; @@ -151,21 +151,21 @@ enum CallbackReason UnknownReason, /** - * This is called once the kernel is ready to use the driver and call @see ConfigurationReason . + * This is called once the kernel is ready to use the module and call @see ConfigurationReason . */ AcknowledgeReason, /** - * This is used after the driver is loaded and the kernel is ready to use the driver. + * This is used after the module is loaded and the kernel is ready to use the module. * * For PCI drivers, @see RawPtr will be the PCI device address. */ ConfigurationReason, /** - * This is used when the kernel wants to stop the driver. + * This is used when the kernel wants to stop the module. * - * The memory allocated by the driver will be freed automatically. + * The memory allocated by the module will be freed automatically. */ StopReason, @@ -174,7 +174,7 @@ enum CallbackReason /* Kernel reserved callbacks. */ /* ------------------------------------------------------- */ - /* Driver callbacks for basic usage. */ + /* Module callbacks for basic usage. */ /** * This is used when the kernel sends data. @@ -193,7 +193,7 @@ enum CallbackReason ReceiveReason, /** - * This is used to adjust driver settings. + * This is used to adjust module settings. * * - Audio * - Volume @@ -202,7 +202,7 @@ enum CallbackReason AdjustReason, /** - * This is used when the kernel wants to query information about the driver. + * This is used when the kernel wants to query information about the module. * * - Input * - Mouse @@ -454,4 +454,4 @@ union CPURegisters __UINT64_TYPE__ raw; } __attribute__((packed)); -#endif // !__FENNIX_DRIVER_API_H__ +#endif // !__FENNIX_MODULE_API_H__ diff --git a/Modules/AHCI/AdvancedHostControllerInterface.cpp b/modules/AHCI/AdvancedHostControllerInterface.cpp similarity index 85% rename from Modules/AHCI/AdvancedHostControllerInterface.cpp rename to modules/AHCI/AdvancedHostControllerInterface.cpp index 64bf496c..9dda1657 100644 --- a/Modules/AHCI/AdvancedHostControllerInterface.cpp +++ b/modules/AHCI/AdvancedHostControllerInterface.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "ahci.hpp" @@ -20,8 +20,8 @@ #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" using namespace PCI; @@ -29,7 +29,7 @@ namespace AdvancedHostControllerInterface { KernelAPI KAPI; - HBAMemory *ABAR; + HBAMemory *AHBA; Port *Ports[32]; uint8_t PortCount = 0; @@ -244,27 +244,28 @@ namespace AdvancedHostControllerInterface } case ConfigurationReason: { - debug("Driver received configuration data."); + debug("Module received configuration data."); PCIBaseAddress = reinterpret_cast(Data->RawPtr); - ABAR = reinterpret_cast(((PCIHeader0 *)PCIBaseAddress)->BAR5); - KAPI.Memory.Map((void *)ABAR, (void *)ABAR, (1 << 1)); + AHBA = reinterpret_cast(((PCIHeader0 *)PCIBaseAddress)->BAR5); + KAPI.Memory.Map((void *)AHBA, (void *)AHBA, (1 << 1)); - uint32_t PortsImplemented = ABAR->PortsImplemented; + uint32_t PortsImplemented = AHBA->PortsImplemented; for (int i = 0; i < 32; i++) { if (PortsImplemented & (1 << i)) { - PortType portType = CheckPortType(&ABAR->Ports[i]); + PortType portType = CheckPortType(&AHBA->Ports[i]); if (portType == PortType::SATA || portType == PortType::SATAPI) { trace("%s drive found at port %d", PortTypeName[portType], i); - Ports[PortCount] = new Port(portType, &ABAR->Ports[i], PortCount); + Ports[PortCount] = new Port(portType, &AHBA->Ports[i], PortCount); PortCount++; } else { if (portType != PortType::None) - warn("Unsupported drive type %s found at port %d", PortTypeName[portType], i); + warn("Unsupported drive type %s found at port %d", + PortTypeName[portType], i); } } } @@ -282,7 +283,7 @@ namespace AdvancedHostControllerInterface case StopReason: { // TODO: Stop the driver. - debug("Driver stopped."); + debug("Module stopped."); break; } case SendReason: @@ -305,7 +306,7 @@ namespace AdvancedHostControllerInterface int InterruptCallback(CPURegisters *) { - /* There's no need to do anything here. */ + /* There is no interrupt handler for AHCI. */ return OK; } } diff --git a/Modules/AHCI/ahci.hpp b/modules/AHCI/ahci.hpp similarity index 83% rename from Modules/AHCI/ahci.hpp rename to modules/AHCI/ahci.hpp index 156ad637..5ffae2e8 100644 --- a/Modules/AHCI/ahci.hpp +++ b/modules/AHCI/ahci.hpp @@ -1,25 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_AHCI_H__ #define __FENNIX_KERNEL_AHCI_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace AdvancedHostControllerInterface { diff --git a/Modules/ATA/AdvancedTechnologyAttachment.cpp b/modules/ATA/AdvancedTechnologyAttachment.cpp similarity index 63% rename from Modules/ATA/AdvancedTechnologyAttachment.cpp rename to modules/ATA/AdvancedTechnologyAttachment.cpp index 84662389..ae625214 100644 --- a/Modules/ATA/AdvancedTechnologyAttachment.cpp +++ b/modules/ATA/AdvancedTechnologyAttachment.cpp @@ -1,11 +1,28 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + #include "ata.hpp" #include #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" namespace AdvancedTechnologyAttachment { @@ -49,7 +66,7 @@ namespace AdvancedTechnologyAttachment } case ConfigurationReason: { - debug("Driver received configuration data."); + debug("Module received configuration data."); break; } case QueryReason: @@ -64,7 +81,7 @@ namespace AdvancedTechnologyAttachment case StopReason: { // TODO: Stop the driver. - debug("Driver stopped."); + debug("Module stopped."); break; } default: diff --git a/modules/ATA/ata.hpp b/modules/ATA/ata.hpp new file mode 100644 index 00000000..6406f805 --- /dev/null +++ b/modules/ATA/ata.hpp @@ -0,0 +1,31 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_ATA_H__ +#define __FENNIX_KERNEL_ATA_H__ + +#include +#include "../../mapi.hpp" + +namespace AdvancedTechnologyAttachment +{ + int DriverEntry(void *); + int CallbackHandler(KernelCallback *); + int InterruptCallback(CPURegisters *); +} + +#endif // !__FENNIX_KERNEL_ATA_H__ diff --git a/Modules/AdvancedMicroDevices/PCNET.cpp b/modules/AdvancedMicroDevices/PCNET.cpp similarity index 72% rename from Modules/AdvancedMicroDevices/PCNET.cpp rename to modules/AdvancedMicroDevices/PCNET.cpp index e7d15a61..3b5330bb 100644 --- a/Modules/AdvancedMicroDevices/PCNET.cpp +++ b/modules/AdvancedMicroDevices/PCNET.cpp @@ -1,3 +1,20 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + #include "pcnet.hpp" #include @@ -5,8 +22,8 @@ #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" using namespace PCI; @@ -68,7 +85,7 @@ namespace PCNET } case ConfigurationReason: { - debug("Driver received configuration data."); + debug("Module received configuration data."); PCIBaseAddress = reinterpret_cast(Data->RawPtr); if (PCIBaseAddress->VendorID == 0x1022 && PCIBaseAddress->DeviceID == 0x2000) { @@ -95,7 +112,7 @@ namespace PCNET case StopReason: { // TODO: Stop the driver. - debug("Driver stopped."); + debug("Module stopped."); break; } default: diff --git a/modules/AdvancedMicroDevices/pcnet.hpp b/modules/AdvancedMicroDevices/pcnet.hpp new file mode 100644 index 00000000..c8fd4204 --- /dev/null +++ b/modules/AdvancedMicroDevices/pcnet.hpp @@ -0,0 +1,38 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_AMD_PCNET_H__ +#define __FENNIX_KERNEL_AMD_PCNET_H__ + +#include +#include "../../mapi.hpp" + +namespace PCNET +{ + struct BARData + { + uint8_t Type; + uint16_t IOBase; + uint64_t MemoryBase; + }; + + int DriverEntry(void *); + int CallbackHandler(KernelCallback *); + int InterruptCallback(CPURegisters *); +} + +#endif // !__FENNIX_KERNEL_AMD_PCNET_H__ diff --git a/Modules/AudioCodec97/AudioCodec97.cpp b/modules/AudioCodec97/AudioCodec97.cpp similarity index 92% rename from Modules/AudioCodec97/AudioCodec97.cpp rename to modules/AudioCodec97/AudioCodec97.cpp index 55550bdd..bf7be3c4 100644 --- a/Modules/AudioCodec97/AudioCodec97.cpp +++ b/modules/AudioCodec97/AudioCodec97.cpp @@ -1,11 +1,28 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + #include "ac97.hpp" #include #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" using namespace PCI; @@ -55,7 +72,7 @@ namespace AudioCodec97 } case ConfigurationReason: { - debug("Driver received configuration data."); + debug("Module received configuration data."); PCIBaseAddress = reinterpret_cast(Data->RawPtr); PCIBaseAddress->Command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; @@ -330,7 +347,7 @@ namespace AudioCodec97 GlobalControl |= GC_ShutDown; outl((uint16_t)(BAR.BusMasterAddress + NABM_GlobalControl), GlobalControl); - debug("Driver stopped."); + debug("Module stopped."); break; } default: diff --git a/Modules/AudioCodec97/ac97.hpp b/modules/AudioCodec97/ac97.hpp similarity index 89% rename from Modules/AudioCodec97/ac97.hpp rename to modules/AudioCodec97/ac97.hpp index 6e73e5c5..b6d1ad40 100644 --- a/Modules/AudioCodec97/ac97.hpp +++ b/modules/AudioCodec97/ac97.hpp @@ -1,25 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_AC97_H__ #define __FENNIX_KERNEL_AC97_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace AudioCodec97 { diff --git a/Modules/Intel/Gigabit.cpp b/modules/Intel/Gigabit.cpp similarity index 91% rename from Modules/Intel/Gigabit.cpp rename to modules/Intel/Gigabit.cpp index 49ab577f..ffb4c831 100644 --- a/Modules/Intel/Gigabit.cpp +++ b/modules/Intel/Gigabit.cpp @@ -1,3 +1,20 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + #include "gigabit.hpp" #include @@ -5,8 +22,8 @@ #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" using namespace PCI; @@ -177,7 +194,7 @@ namespace Gigabit } case ConfigurationReason: { - debug("Driver received configuration data."); + debug("Module received configuration data."); PCIBaseAddress = reinterpret_cast(Data->RawPtr); switch (PCIBaseAddress->DeviceID) { @@ -344,7 +361,7 @@ namespace Gigabit // Powering down the device (?) WriteCMD(REG::CTRL, PCTRL::POWER_DOWN); /* TODO: Stop link; further testing required */ - debug("Driver stopped."); + debug("Module stopped."); break; } default: @@ -366,7 +383,7 @@ namespace Gigabit { uint8_t *Data = (uint8_t *)RX[RXCurrent]->Address; uint16_t DataLength = RX[RXCurrent]->Length; - KAPI.Command.Network.ReceivePacket(KAPI.Info.DriverUID, Data, DataLength); + KAPI.Command.Network.ReceivePacket(KAPI.Info.modUniqueID, Data, DataLength); RX[RXCurrent]->Status = 0; uint16_t OldRXCurrent = RXCurrent; RXCurrent = (uint16_t)((RXCurrent + 1) % E1000_NUM_RX_DESC); diff --git a/Modules/Intel/gigabit.hpp b/modules/Intel/gigabit.hpp similarity index 80% rename from Modules/Intel/gigabit.hpp rename to modules/Intel/gigabit.hpp index 5291e937..24d449ea 100644 --- a/Modules/Intel/gigabit.hpp +++ b/modules/Intel/gigabit.hpp @@ -1,25 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_INTEL_GIGABIT_H__ #define __FENNIX_KERNEL_INTEL_GIGABIT_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace Gigabit { diff --git a/modules/PersonalSystem2/Keyboard.cpp b/modules/PersonalSystem2/Keyboard.cpp new file mode 100644 index 00000000..e41f40a4 --- /dev/null +++ b/modules/PersonalSystem2/Keyboard.cpp @@ -0,0 +1,227 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "keyboard.hpp" + +#include +#include +#include + +#include "../../mapi.hpp" +#include "../mod.hpp" +#include "../../kernel.h" + +namespace PS2Keyboard +{ + KernelAPI KAPI; + + uint8_t ScanCode = 0; + bool InputReceived = false; + + void PS2Wait(bool Read) + { + int Timeout = 100000; + uint8_t Status = 0; + while (Timeout--) + { + Status = inb(0x64); + if (Read) + { + if ((Status & 1) == 1) + return; + } + else + { + if ((Status & 2) == 0) + return; + } + } + } + + int DriverEntry(void *Data) + { + if (!Data) + return INVALID_KERNEL_API; + KAPI = *(KernelAPI *)Data; + if (KAPI.Version.Major < 0 || KAPI.Version.Minor < 0 || KAPI.Version.Patch < 0) + return KERNEL_API_VERSION_NOT_SUPPORTED; + + return OK; + } + + int CallbackHandler(KernelCallback *Data) + { + switch (Data->Reason) + { + case AcknowledgeReason: + { + debug("Kernel acknowledged the driver."); + break; + } + case ConfigurationReason: + { +#define WaitRead PS2Wait(true) +#define WaitWrite PS2Wait(false) + + WaitWrite; + outb(0x64, 0xAD); + WaitWrite; + outb(0x64, 0xA7); + + WaitRead; + inb(0x60); + + WaitWrite; + outb(0x64, 0x20); + WaitRead; + uint8_t cfg = inb(0x60); + bool DualChannel = cfg & 0b00100000; + if (DualChannel) + trace("Dual channel PS/2 controller detected."); + cfg |= 0b01000011; + WaitWrite; + outb(0x64, 0x60); + WaitWrite; + outb(0x60, cfg); + + WaitWrite; + outb(0x64, 0xAA); + WaitRead; + uint8_t test = inb(0x60); + if (test != 0x55) + { + error("PS/2 controller self test failed! (%#x)", test); + printf("PS/2 controller self test failed! (%#x)\n", test); + CPU::Stop(); + } + + WaitWrite; + outb(0x64, 0x60); + WaitWrite; + outb(0x60, cfg); + + bool DCExists = false; + if (DualChannel) + { + WaitWrite; + outb(0x64, 0xAE); + WaitWrite; + outb(0x64, 0x20); + WaitRead; + cfg = inb(0x60); + DCExists = !(cfg & 0b00100000); + WaitWrite; + outb(0x64, 0xAD); + debug("DCExists: %d", DCExists); + } + + WaitWrite; + outb(0x64, 0xAB); + WaitRead; + test = inb(0x60); + if (test != 0x00) + { + error("PS/2 keyboard self test failed! (%#x)", test); + printf("PS/2 keyboard self test failed! (%#x)\n", test); + CPU::Stop(); + } + + if (DCExists) + { + WaitWrite; + outb(0x64, 0xA9); + WaitRead; + test = inb(0x60); + if (test != 0x00) + { + error("PS/2 mouse self test failed! (%#x)", test); + printf("PS/2 mouse self test failed! (%#x)\n", test); + CPU::Stop(); + } + } + + WaitWrite; + outb(0x64, 0xAE); + + if (DCExists) + { + WaitWrite; + outb(0x64, 0xA8); + } + + WaitWrite; + outb(0x60, 0xFF); + WaitRead; + test = inb(0x60); + if (test == 0xFC) + { + error("PS/2 keyboard reset failed! (%#x)", test); + printf("PS/2 keyboard reset failed! (%#x)\n", test); + CPU::Stop(); + } + + WaitWrite; + outb(0x60, 0xD4); + WaitWrite; + outb(0x60, 0xFF); + WaitRead; + test = inb(0x60); + if (test == 0xFC) + { + error("PS/2 mouse reset failed! (%#x)", test); + printf("PS/2 mouse reset failed! (%#x)\n", test); + CPU::Stop(); + } + + trace("PS/2 keyboard configured."); + break; + } + case QueryReason: + { + Data->InputCallback.Keyboard.Key = ScanCode; + break; + } + case PollWaitReason: + { + while (!InputReceived) + TaskManager->Yield(); + InputReceived = false; + + Data->InputCallback.Keyboard.Key = ScanCode; + break; + } + case StopReason: + { + fixme("Module stopped."); + break; + } + default: + { + warn("Unknown reason."); + break; + } + } + return OK; + } + + int InterruptCallback(CPURegisters *) + { + ScanCode = inb(0x60); + InputReceived = true; + return OK; + } +} diff --git a/Modules/PersonalSystem2/Mouse.cpp b/modules/PersonalSystem2/Mouse.cpp similarity index 85% rename from Modules/PersonalSystem2/Mouse.cpp rename to modules/PersonalSystem2/Mouse.cpp index 4323a6bd..d8430579 100644 --- a/Modules/PersonalSystem2/Mouse.cpp +++ b/modules/PersonalSystem2/Mouse.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "mouse.hpp" @@ -20,8 +20,8 @@ #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" #include "../../kernel.h" namespace PS2Mouse @@ -136,7 +136,7 @@ namespace PS2Mouse Write(DATA, 0xF5); Read(); - debug("Driver stopped."); + debug("Module stopped."); break; } default: diff --git a/Modules/PersonalSystem2/keyboard.hpp b/modules/PersonalSystem2/keyboard.hpp similarity index 84% rename from Modules/PersonalSystem2/keyboard.hpp rename to modules/PersonalSystem2/keyboard.hpp index f565a1ad..4c24cb37 100644 --- a/Modules/PersonalSystem2/keyboard.hpp +++ b/modules/PersonalSystem2/keyboard.hpp @@ -1,25 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_PS2_KEYBOARD_H__ #define __FENNIX_KERNEL_PS2_KEYBOARD_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace PS2Keyboard { diff --git a/Modules/PersonalSystem2/mouse.hpp b/modules/PersonalSystem2/mouse.hpp similarity index 50% rename from Modules/PersonalSystem2/mouse.hpp rename to modules/PersonalSystem2/mouse.hpp index c8ceec75..a7fedd24 100644 --- a/Modules/PersonalSystem2/mouse.hpp +++ b/modules/PersonalSystem2/mouse.hpp @@ -1,25 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_PS2_MOUSE_H__ #define __FENNIX_KERNEL_PS2_MOUSE_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace PS2Mouse { diff --git a/Modules/Realtek/RTL8139.cpp b/modules/Realtek/RTL8139.cpp similarity index 83% rename from Modules/Realtek/RTL8139.cpp rename to modules/Realtek/RTL8139.cpp index 01cc24bc..eee1933f 100644 --- a/Modules/Realtek/RTL8139.cpp +++ b/modules/Realtek/RTL8139.cpp @@ -1,3 +1,20 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + #include "rtl8139.hpp" #include @@ -5,8 +22,8 @@ #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" using namespace PCI; @@ -110,7 +127,7 @@ namespace RTL8139 } case ConfigurationReason: { - debug("Driver received configuration data."); + debug("Module received configuration data."); PCIBaseAddress = reinterpret_cast(Data->RawPtr); if (PCIBaseAddress->VendorID == 0x10EC && PCIBaseAddress->DeviceID == 0x8139) { @@ -158,7 +175,7 @@ namespace RTL8139 case StopReason: { // TODO: Stop the driver. - debug("Driver stopped."); + debug("Module stopped."); break; } default: @@ -178,7 +195,7 @@ namespace RTL8139 uint16_t *Data = (uint16_t *)(RXBuffer + CurrentPacket); uint16_t DataLength = *(Data + 1); Data = Data + 2; - KAPI.Command.Network.ReceivePacket(KAPI.Info.DriverUID, (uint8_t *)Data, DataLength); + KAPI.Command.Network.ReceivePacket(KAPI.Info.modUniqueID, (uint8_t *)Data, DataLength); CurrentPacket = (uint16_t)((CurrentPacket + DataLength + 4 + 3) & (~3)); if (CurrentPacket > 8192) CurrentPacket -= 8192; diff --git a/Modules/Realtek/rtl8139.hpp b/modules/Realtek/rtl8139.hpp similarity index 97% rename from Modules/Realtek/rtl8139.hpp rename to modules/Realtek/rtl8139.hpp index 77030915..cf801e60 100644 --- a/Modules/Realtek/rtl8139.hpp +++ b/modules/Realtek/rtl8139.hpp @@ -19,7 +19,7 @@ #define __FENNIX_KERNEL_RTL8139_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace RTL8139 { diff --git a/Modules/VMware/Mouse.cpp b/modules/VMware/Mouse.cpp similarity index 87% rename from Modules/VMware/Mouse.cpp rename to modules/VMware/Mouse.cpp index 86bea919..2e870455 100644 --- a/Modules/VMware/Mouse.cpp +++ b/modules/VMware/Mouse.cpp @@ -1,10 +1,27 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + #include "mouse.hpp" #include #include -#include "../../DAPI.hpp" -#include "../drv.hpp" +#include "../../mapi.hpp" +#include "../mod.hpp" #include "../../kernel.h" /* https://wiki.osdev.org/VMware_tools */ @@ -196,7 +213,7 @@ namespace VMwareMouse Write(COMMAND, 0xD4); Write(DATA, 0xF5); Read(); - debug("Driver stopped."); + debug("Module stopped."); break; } default: diff --git a/Modules/VMware/mouse.hpp b/modules/VMware/mouse.hpp similarity index 56% rename from Modules/VMware/mouse.hpp rename to modules/VMware/mouse.hpp index a56af7be..9ae895ef 100644 --- a/Modules/VMware/mouse.hpp +++ b/modules/VMware/mouse.hpp @@ -1,25 +1,25 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_VMWARE_MOUSE_H__ #define __FENNIX_KERNEL_VMWARE_MOUSE_H__ #include -#include "../../DAPI.hpp" +#include "../../mapi.hpp" namespace VMwareMouse { diff --git a/Modules/drv.hpp b/modules/mod.hpp similarity index 87% rename from Modules/drv.hpp rename to modules/mod.hpp index 16b0f6f2..031949cf 100644 --- a/Modules/drv.hpp +++ b/modules/mod.hpp @@ -15,8 +15,8 @@ along with Fennix Kernel. If not, see . */ -#ifndef __FENNIX_KERNEL_DRV_H__ -#define __FENNIX_KERNEL_DRV_H__ +#ifndef __FENNIX_KERNEL_MOD_H__ +#define __FENNIX_KERNEL_MOD_H__ #include @@ -30,4 +30,6 @@ bool StartRTL8139(); bool StartPCNET(); bool StartGigabit(); -#endif // !__FENNIX_KERNEL_DRV_H__ +void StartBuiltInModules(); + +#endif // !__FENNIX_KERNEL_MOD_H__ diff --git a/Modules/BuiltinModuleLoader.cpp b/modules/mod_loader.cpp similarity index 65% rename from Modules/BuiltinModuleLoader.cpp rename to modules/mod_loader.cpp index 64bc3f19..3f601da8 100644 --- a/Modules/BuiltinModuleLoader.cpp +++ b/modules/mod_loader.cpp @@ -1,21 +1,21 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ -#include "drv.hpp" +#include "mod.hpp" #include "AHCI/ahci.hpp" #include "VMware/mouse.hpp" @@ -30,18 +30,18 @@ #include #include -#include "../Core/Driver/api.hpp" +#include "../core/module/api.hpp" #include "../kernel.h" -#include "../DAPI.hpp" +#include "../mapi.hpp" #include "../Fex.hpp" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-field-initializers" FexExtended AHCIExtendedHeader = { - .Driver = { + .Module = { .Name = "Advanced Host Controller Interface", - .Type = FexDriverType_Storage, + .Type = FexModuleType_Storage, .Callback = AdvancedHostControllerInterface::CallbackHandler, .InterruptCallback = AdvancedHostControllerInterface::InterruptCallback, .Bind = { @@ -55,9 +55,9 @@ FexExtended AHCIExtendedHeader = { }}}}; FexExtended VMwareVirtualMouseExtendedHeader = { - .Driver = { + .Module = { .Name = "VMware Virtual Mouse", - .Type = FexDriverType_Input, + .Type = FexModuleType_Input, .TypeFlags = FexDriverInputTypes_Mouse, .OverrideOnConflict = true, .Callback = VMwareMouse::CallbackHandler, @@ -69,9 +69,9 @@ FexExtended VMwareVirtualMouseExtendedHeader = { }}}}; FexExtended PS2MouseExtendedHeader = { - .Driver = { + .Module = { .Name = "PS/2 Mouse", - .Type = FexDriverType_Input, + .Type = FexModuleType_Input, .TypeFlags = FexDriverInputTypes_Mouse, .Callback = PS2Mouse::CallbackHandler, .InterruptCallback = PS2Mouse::InterruptCallback, @@ -82,9 +82,9 @@ FexExtended PS2MouseExtendedHeader = { }}}}; FexExtended PS2KeyboardExtendedHeader = { - .Driver = { + .Module = { .Name = "PS/2 Keyboard", - .Type = FexDriverType_Input, + .Type = FexModuleType_Input, .TypeFlags = FexDriverInputTypes_Keyboard, .Callback = PS2Keyboard::CallbackHandler, .InterruptCallback = PS2Keyboard::InterruptCallback, @@ -95,9 +95,9 @@ FexExtended PS2KeyboardExtendedHeader = { }}}}; FexExtended ATAExtendedHeader = { - .Driver = { + .Module = { .Name = "Advanced Technology Attachment", - .Type = FexDriverType_Storage, + .Type = FexModuleType_Storage, .Callback = AdvancedTechnologyAttachment::CallbackHandler, .InterruptCallback = AdvancedTechnologyAttachment::InterruptCallback, .Bind = { @@ -107,9 +107,9 @@ FexExtended ATAExtendedHeader = { }}}}; FexExtended AC97ExtendedHeader = { - .Driver = { - .Name = "Audio Codec '97 Driver", - .Type = FexDriverType_Audio, + .Module = { + .Name = "Audio Codec '97 Module", + .Type = FexModuleType_Audio, .TypeFlags = FexDriverInputTypes_None, .OverrideOnConflict = false, .Callback = AudioCodec97::CallbackHandler, @@ -125,9 +125,9 @@ FexExtended AC97ExtendedHeader = { }}}}; FexExtended RTL8139ExtendedHeader = { - .Driver = { + .Module = { .Name = "Realtek RTL8139", - .Type = FexDriverType_Network, + .Type = FexModuleType_Network, .Callback = RTL8139::CallbackHandler, .InterruptCallback = RTL8139::InterruptCallback, .Bind = { @@ -141,9 +141,9 @@ FexExtended RTL8139ExtendedHeader = { }}}}; FexExtended AMDPCNETExtendedHeader = { - .Driver = { + .Module = { .Name = "Advanced Micro Devices PCNET", - .Type = FexDriverType_Network, + .Type = FexModuleType_Network, .Callback = PCNET::CallbackHandler, .InterruptCallback = PCNET::InterruptCallback, .Bind = { @@ -157,9 +157,9 @@ FexExtended AMDPCNETExtendedHeader = { }}}}; FexExtended IntelGigabitExtendedHeader = { - .Driver = { + .Module = { .Name = "Intel Gigabit Ethernet Controller", - .Type = FexDriverType_Network, + .Type = FexModuleType_Network, .Callback = Gigabit::CallbackHandler, .InterruptCallback = Gigabit::InterruptCallback, .Bind = { @@ -174,7 +174,7 @@ FexExtended IntelGigabitExtendedHeader = { #pragma GCC diagnostic pop -std::vector FindPCI(uint16_t VendorID[16], uint16_t DeviceID[16]) +std::vector FindPCI(uint16_t VendorID[16], uint16_t DeviceID[16]) { for (uint16_t Vidx = 0; Vidx < 16; Vidx++) { @@ -183,7 +183,7 @@ std::vector FindPCI(uint16_t VendorID[16], uint16_t Devi if (VendorID[Vidx] == 0 || DeviceID[Didx] == 0) break; - std::vector devices = PCIManager->FindPCIDevice(VendorID[Vidx], DeviceID[Didx]); + std::vector devices = PCIManager->FindPCIDevice(VendorID[Vidx], DeviceID[Didx]); if (devices.size() == 0) continue; @@ -192,16 +192,16 @@ std::vector FindPCI(uint16_t VendorID[16], uint16_t Devi } warn("No PCI device found"); - return std::vector(); + return std::vector(); } bool StartAHCI() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = AdvancedHostControllerInterface::DriverEntry, .ExtendedHeader = &AHCIExtendedHeader}; - if (DriverManager->DriverLoadBindPCI((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindPCI((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -209,11 +209,11 @@ bool StartAHCI() bool StartVMwareMouse() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = VMwareMouse::DriverEntry, .ExtendedHeader = &VMwareVirtualMouseExtendedHeader}; - if (DriverManager->DriverLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -221,11 +221,11 @@ bool StartVMwareMouse() bool StartPS2Mouse() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = PS2Mouse::DriverEntry, .ExtendedHeader = &PS2MouseExtendedHeader}; - if (DriverManager->DriverLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -233,11 +233,11 @@ bool StartPS2Mouse() bool StartPS2Keyboard() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = PS2Keyboard::DriverEntry, .ExtendedHeader = &PS2KeyboardExtendedHeader}; - if (DriverManager->DriverLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -245,11 +245,11 @@ bool StartPS2Keyboard() bool StartATA() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = AdvancedTechnologyAttachment::DriverEntry, .ExtendedHeader = &ATAExtendedHeader}; - if (DriverManager->DriverLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindInterrupt((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -257,11 +257,11 @@ bool StartATA() bool StartAC97() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = AudioCodec97::DriverEntry, .ExtendedHeader = &AC97ExtendedHeader}; - if (DriverManager->DriverLoadBindPCI((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindPCI((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -269,11 +269,11 @@ bool StartAC97() bool StartRTL8139() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = RTL8139::DriverEntry, .ExtendedHeader = &RTL8139ExtendedHeader}; - if (DriverManager->DriverLoadBindPCI((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindPCI((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -281,11 +281,11 @@ bool StartRTL8139() bool StartPCNET() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = PCNET::DriverEntry, .ExtendedHeader = &AMDPCNETExtendedHeader}; - if (DriverManager->DriverLoadBindPCI((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindPCI((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; @@ -293,12 +293,25 @@ bool StartPCNET() bool StartGigabit() { - Driver::BuiltInDriverInfo BIDI = { + Module::BuiltInModuleInfo BIDI = { .EntryPoint = Gigabit::DriverEntry, .ExtendedHeader = &IntelGigabitExtendedHeader}; - if (DriverManager->DriverLoadBindPCI((uintptr_t)&BIDI, 0, true) == Driver::DriverCode::OK) + if (ModuleManager->ModuleLoadBindPCI((uintptr_t)&BIDI, 0, true) == Module::ModuleCode::OK) return true; return false; } + +void StartBuiltInModules() +{ + StartAHCI(); + StartVMwareMouse(); + StartPS2Mouse(); + StartPS2Keyboard(); + StartATA(); + StartAC97(); + StartRTL8139(); + StartPCNET(); + StartGigabit(); +} diff --git a/Network/AddressResolutionProtocol.cpp b/network/arp.cpp similarity index 91% rename from Network/AddressResolutionProtocol.cpp rename to network/arp.cpp index 8c4f63e8..354d3762 100644 --- a/Network/AddressResolutionProtocol.cpp +++ b/network/arp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/network/checksum.cpp b/network/checksum.cpp new file mode 100644 index 00000000..2edac754 --- /dev/null +++ b/network/checksum.cpp @@ -0,0 +1,31 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +uint16_t CalculateChecksum(uint16_t *Data, size_t Length) +{ + uint16_t *Data16 = (uint16_t *)Data; + uint64_t Checksum = 0; + for (uint64_t i = 0; i < Length / 2; i++) + Checksum += ((Data16[i] & 0xFF00) >> 8) | ((Data16[i] & 0x00FF) << 8); + if (Length % 2) + Checksum += ((uint16_t)((char *)Data16)[Length - 1]) << 8; + while (Checksum & 0xFFFF0000) + Checksum = (Checksum & 0xFFFF) + (Checksum >> 16); + return (uint16_t)(((~Checksum & 0xFF00) >> 8) | ((~Checksum & 0x00FF) << 8)); +} diff --git a/Network/DynamicHostConfigurationProtocol.cpp b/network/dhcp.cpp similarity index 89% rename from Network/DynamicHostConfigurationProtocol.cpp rename to network/dhcp.cpp index 3f0380a4..db930516 100644 --- a/Network/DynamicHostConfigurationProtocol.cpp +++ b/network/dhcp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/network/dns.cpp b/network/dns.cpp new file mode 100644 index 00000000..98c46adf --- /dev/null +++ b/network/dns.cpp @@ -0,0 +1,35 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +#include "../kernel.h" + +namespace NetworkDNS +{ + DNS::DNS(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents() + { + debug("DNS interface %#lx created.", this); + this->UDPSocket = Socket; + } + + DNS::~DNS() + { + debug("DNS interface %#lx destroyed.", this); + } +} diff --git a/Network/Ethernet.cpp b/network/eth.cpp similarity index 85% rename from Network/Ethernet.cpp rename to network/eth.cpp index eb5b87d3..265012f3 100644 --- a/Network/Ethernet.cpp +++ b/network/eth.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -38,6 +38,7 @@ namespace NetworkEthernet debug("Ethernet interface %#lx created.", this); this->Interface = Interface; } + Ethernet::~Ethernet() { debug("Ethernet interface %#lx destroyed.", this); @@ -76,7 +77,7 @@ namespace NetworkEthernet /* Byte-swapped little-endian */ if (b48(Packet->Header.DestinationMAC) == 0xFFFFFFFFFFFF || - /* Byte-swapped Driver interface has little-endian order */ + /* Byte-swapped Module interface has little-endian order */ b48(Packet->Header.DestinationMAC) == this->Interface->MAC.ToHex()) /* This is true only if the packet is for us (Interface MAC or broadcast) */ { diff --git a/Network/InternetControlMessageProtocol.cpp b/network/icmp.cpp similarity index 68% rename from Network/InternetControlMessageProtocol.cpp rename to network/icmp.cpp index 3851a9ec..1bc3788a 100644 --- a/Network/InternetControlMessageProtocol.cpp +++ b/network/icmp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Network/InternetProtocol.cpp b/network/ip.cpp similarity index 87% rename from Network/InternetProtocol.cpp rename to network/ip.cpp index 562d4397..c6075fc6 100644 --- a/Network/InternetProtocol.cpp +++ b/network/ip.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Network/NetworkDebugger.cpp b/network/net_dbg.cpp similarity index 80% rename from Network/NetworkDebugger.cpp rename to network/net_dbg.cpp index 9284c96a..65d9b067 100644 --- a/Network/NetworkDebugger.cpp +++ b/network/net_dbg.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Network/NetworkController.cpp b/network/network_controller.cpp similarity index 78% rename from Network/NetworkController.cpp rename to network/network_controller.cpp index 0043de27..229bee4e 100644 --- a/Network/NetworkController.cpp +++ b/network/network_controller.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -27,7 +27,7 @@ #include #include "../kernel.h" -#include "../DAPI.hpp" +#include "../mapi.hpp" #include "../Fex.hpp" /* FIXME: The functions MUST have little endian parameters and return values. */ @@ -38,12 +38,12 @@ namespace NetworkInterfaceManager NetworkInterface::NetworkInterface() { - mem = new Memory::MemMgr(nullptr, thisProcess->memDirectory); - if (DriverManager->GetDrivers().size() > 0) + this->vma = new Memory::VirtualMemoryArea(nullptr); + if (ModuleManager->GetModules().size() > 0) { - foreach (auto Driver in DriverManager->GetDrivers()) - if (((FexExtended *)Driver.ExtendedHeaderAddress)->Driver.Type == FexDriverType::FexDriverType_Network) - this->FetchNetworkCards(Driver.DriverUID); + foreach (auto Module in ModuleManager->GetModules()) + if (((FexExtended *)Module.ExtendedHeaderAddress)->Module.Type == FexModuleType::FexModuleType_Network) + this->FetchNetworkCards(Module.modUniqueID); } else KPrint("\eE85230No network drivers found! Cannot fetch network cards!"); @@ -65,20 +65,20 @@ namespace NetworkInterfaceManager Interfaces.clear(); // Delete all interfaces and their callbacks and free the memory - delete mem, mem = nullptr; + delete this->vma, this->vma = nullptr; } - void NetworkInterface::FetchNetworkCards(unsigned long DriverUID) + void NetworkInterface::FetchNetworkCards(unsigned long modUniqueID) { KernelCallback cb{}; cb.Reason = QueryReason; - DriverManager->IOCB(DriverUID, &cb); + ModuleManager->IOCB(modUniqueID, &cb); - DeviceInterface *Iface = (DeviceInterface *)mem->RequestPages(TO_PAGES(sizeof(DeviceInterface) + 1)); + DeviceInterface *Iface = (DeviceInterface *)vma->RequestPages(TO_PAGES(sizeof(DeviceInterface) + 1)); strcpy(Iface->Name, cb.NetworkCallback.Fetch.Name); Iface->ID = this->CardIDs++; Iface->MAC.FromHex(cb.NetworkCallback.Fetch.MAC); - Iface->DriverID = DriverUID; + Iface->DriverID = modUniqueID; Interfaces.push_back(Iface); foreach (auto var in RegisteredEvents) @@ -187,18 +187,18 @@ namespace NetworkInterfaceManager void NetworkInterface::Send(DeviceInterface *Interface, uint8_t *Data, size_t Length) { - void *DataToBeSent = mem->RequestPages(TO_PAGES(Length + 1)); + void *DataToBeSent = vma->RequestPages(TO_PAGES(Length + 1)); memcpy(DataToBeSent, Data, Length); KernelCallback cb{}; cb.Reason = SendReason; cb.NetworkCallback.Send.Data = (uint8_t *)DataToBeSent; cb.NetworkCallback.Send.Length = Length; - DriverManager->IOCB(Interface->DriverID, &cb); + ModuleManager->IOCB(Interface->DriverID, &cb); - mem->FreePages(DataToBeSent, TO_PAGES(Length + 1)); - foreach (auto var in RegisteredEvents) - var->OnInterfaceSent(Interface, Data, Length); + vma->FreePages(DataToBeSent, TO_PAGES(Length + 1)); + foreach (auto ev in RegisteredEvents) + ev->OnInterfaceSent(Interface, Data, Length); } void NetworkInterface::Receive(DeviceInterface *Interface, uint8_t *Data, size_t Length) diff --git a/Network/NetworkTimeProtocol.cpp b/network/ntp.cpp similarity index 72% rename from Network/NetworkTimeProtocol.cpp rename to network/ntp.cpp index d11433df..9fe7717e 100644 --- a/Network/NetworkTimeProtocol.cpp +++ b/network/ntp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/network/tcp.cpp b/network/tcp.cpp new file mode 100644 index 00000000..61b7fc43 --- /dev/null +++ b/network/tcp.cpp @@ -0,0 +1,25 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +#include "../kernel.h" + +namespace NetworkTCP +{ +} diff --git a/Network/UserDatagramProtocol.cpp b/network/udp.cpp similarity index 86% rename from Network/UserDatagramProtocol.cpp rename to network/udp.cpp index bd6d8d0d..3791b081 100644 --- a/Network/UserDatagramProtocol.cpp +++ b/network/udp.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/Profiling/cyg.cpp b/profiling/cyg.cpp similarity index 78% rename from Profiling/cyg.cpp rename to profiling/cyg.cpp index ba5c3b34..a12f83e7 100644 --- a/Profiling/cyg.cpp +++ b/profiling/cyg.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -26,12 +26,13 @@ bool Wait = false; unsigned long long LogDepth = 0; unsigned int Level = 0; using namespace UniversalAsynchronousReceiverTransmitter; +UART com2(COM2); static inline SafeFunction NIF void profiler_uart_wrapper(char c, void *unused) { bool renable = EnableProfiler; EnableProfiler = false; - UART(COM2).Write(c); + com2.Write(c); UNUSED(unused); if (renable) EnableProfiler = true; diff --git a/Profiling/gcov.cpp b/profiling/gcov.cpp similarity index 66% rename from Profiling/gcov.cpp rename to profiling/gcov.cpp index b5277f60..c3d4866d 100644 --- a/Profiling/gcov.cpp +++ b/profiling/gcov.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include diff --git a/profiling/gprof.cpp b/profiling/gprof.cpp new file mode 100644 index 00000000..afd3d4b2 --- /dev/null +++ b/profiling/gprof.cpp @@ -0,0 +1,38 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include + +#include "../kernel.h" + +using namespace UniversalAsynchronousReceiverTransmitter; + +static inline SafeFunction NIF void gprof_uart_wrapper(char c, void *unused) +{ + UART(COM2).Write(c); + UNUSED(unused); +} + +EXTERNC SafeFunction NIF void mcount(unsigned long frompc, unsigned long selfpc) +{ + // TODO: Implement + /* https://docs.kernel.org/trace/ftrace-design.html */ + UNUSED(frompc); + UNUSED(selfpc); +} diff --git a/FileSystem/FileDescriptor.cpp b/storage/file_descriptor.cpp similarity index 67% rename from FileSystem/FileDescriptor.cpp rename to storage/file_descriptor.cpp index 7fc30cb9..d6279ec8 100644 --- a/FileSystem/FileDescriptor.cpp +++ b/storage/file_descriptor.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -27,43 +27,46 @@ #include "../kernel.h" -namespace VirtualFileSystem +namespace vfs { - ReadFSFunction(fd_Read) - { - if (Size <= 0) - Size = node->Length; + // ReadFSFunction(fd_Read) + // { + // if (Size <= 0) + // Size = node->Length; - if (RefOffset > node->Length) - return 0; + // if (RefOffset > node->Length) + // return 0; - if (RefOffset + (off_t)Size > node->Length) - Size = node->Length - RefOffset; + // if ((node->Length - RefOffset) == 0) + // return 0; /* EOF */ - memcpy(Buffer, (uint8_t *)(node->Address + RefOffset), Size); - return Size; - } + // if (RefOffset + (off_t)Size > node->Length) + // Size = node->Length; - WriteFSFunction(fd_Write) - { - if (Size <= 0) - Size = node->Length; + // memcpy(Buffer, (uint8_t *)(node->Address + RefOffset), Size); + // return Size; + // } - if (RefOffset > node->Length) - return 0; + // WriteFSFunction(fd_Write) + // { + // if (Size <= 0) + // Size = node->Length; - if (RefOffset + (off_t)Size > node->Length) - Size = node->Length - RefOffset; + // if (RefOffset > node->Length) + // return 0; - memcpy((uint8_t *)(node->Address + RefOffset), Buffer, Size); - return Size; - } + // if (RefOffset + (off_t)Size > node->Length) + // Size = node->Length; - VirtualFileSystem::FileSystemOperations fd_op = { - .Name = "fd", - // .Read = fd_Read, - // .Write = fd_Write, - }; + // memcpy((uint8_t *)(node->Address + RefOffset), Buffer, Size); + // return Size; + // } + + // vfs::FileSystemOperations fd_op = { + // .Name = "fd", + // // .Read = fd_Read, + // // .Write = fd_Write, + // }; FileDescriptorTable::Fildes FileDescriptorTable::GetFileDescriptor(int FileDescriptor) @@ -95,23 +98,35 @@ namespace VirtualFileSystem int FileDescriptorTable::ProbeMode(mode_t Mode, int Flags) { + if (!(Flags & O_CREAT)) + return 0; + if (Flags & O_RDONLY) { if (!(Mode & S_IRUSR)) + { + debug("No read permission (%d)", Mode); return -EACCES; + } } if (Flags & O_WRONLY) { if (!(Mode & S_IWUSR)) + { + debug("No write permission (%d)", Mode); return -EACCES; + } } if (Flags & O_RDWR) { if (!(Mode & S_IRUSR) || !(Mode & S_IWUSR)) + { + debug("No read/write permission (%d)", Mode); return -EACCES; + } } return 0; @@ -123,35 +138,41 @@ namespace VirtualFileSystem Tasking::PCB *pcb = thisProcess; if (ProbeMode(Mode, Flags) < 0) - { - errno = EACCES; - return -1; - } + return -EACCES; if (Flags & O_CREAT) { - Node *n = vfs->Create(AbsolutePath, - NodeFlags::FILE, - pcb->CurrentWorkingDirectory); + int ret; + Node *n = new Node(pcb->CurrentWorkingDirectory, + AbsolutePath, + NodeType::FILE, + cwk_path_is_absolute(AbsolutePath), + fs, + &ret); - if (!n) + if (ret == -EEXIST) { debug("%s: File already exists, continuing...", AbsolutePath); } + else if (ret < 0) + { + error("Failed to create file %s: %d", + AbsolutePath, ret); + assert(false); + } } if (Flags & O_EXCL) { - RefNode *File = vfs->Open(AbsolutePath, - pcb->CurrentWorkingDirectory); + RefNode *File = fs->Open(AbsolutePath, + pcb->CurrentWorkingDirectory); if (!File) { - errno = EEXIST; - error("Failed to open file %s: %d", - AbsolutePath, errno); - return -1; + error("Failed to open file %s", + AbsolutePath); + return -EIO; } } @@ -170,23 +191,20 @@ namespace VirtualFileSystem fixme("O_CLOEXEC"); } - RefNode *File = vfs->Open(AbsolutePath, - pcb->CurrentWorkingDirectory); + RefNode *File = fs->Open(AbsolutePath, + pcb->CurrentWorkingDirectory); if (!File) { - error("Failed to open file %s: %d", - AbsolutePath, errno); - return -1; + error("Failed to open file %s", + AbsolutePath); + return -EIO; } Fildes fd = {.Descriptor = GetFreeFileDescriptor()}; if (fd.Descriptor < 0) - { - errno = EMFILE; - return -1; - } + return -EMFILE; fd.Mode = Mode; fd.Flags = Flags; @@ -196,13 +214,11 @@ namespace VirtualFileSystem char FileName[64]; sprintf(FileName, "%d", fd.Descriptor); - VirtualFileSystem::Node *n = vfs->Create(FileName, VirtualFileSystem::NodeFlags::FILE, this->fdDir); + vfs::Node *n = fs->Create(FileName, vfs::NodeType::FILE, this->fdDir); if (n) { /* FIXME: Implement proper file descriptors */ - n->Address = (uintptr_t)0xdeadbeef; - n->Length = File->FileSize; - n->Operator = &fd_op; + n->Size = File->FileSize; } return fd.Descriptor; @@ -218,7 +234,7 @@ namespace VirtualFileSystem char FileName[64]; sprintf(FileName, "%d", FileDescriptor); - vfs->Delete(FileName, false, this->fdDir); + fs->Delete(FileName, false, this->fdDir); return 0; } } @@ -231,13 +247,12 @@ namespace VirtualFileSystem char FileName[64]; sprintf(FileName, "%d", FileDescriptor); - vfs->Delete(FileName, false, this->fdDir); + fs->Delete(FileName, false, this->fdDir); return 0; } } - errno = EBADF; - return -1; + return -EBADF; } int FileDescriptorTable::GetFreeFileDescriptor() @@ -272,11 +287,10 @@ namespace VirtualFileSystem i++; } - errno = EMFILE; - return -1; + return -EMFILE; } - std::string FileDescriptorTable::GetAbsolutePath(int FileDescriptor) + const char *FileDescriptorTable::GetAbsolutePath(int FileDescriptor) { Fildes fd = this->GetFileDescriptor(FileDescriptor); DupFildes dfd = this->GetDupFildes(FileDescriptor); @@ -292,8 +306,8 @@ namespace VirtualFileSystem hnd = dfd.Handle; Node *node = hnd->node; - std::string absolutePath = vfs->GetPathFromNode(node); - std::string path = absolutePath.c_str(); + const char *path = new char[strlen(node->FullPath) + 1]; + strcpy((char *)path, node->FullPath); return path; } @@ -301,10 +315,7 @@ namespace VirtualFileSystem mode_t mode) { if (pathname == nullptr) - { - errno = EFAULT; - return -1; - } + return -EFAULT; return AddFileDescriptor(pathname, mode, flags); } @@ -321,8 +332,7 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } RefNode *hnd = nullptr; @@ -331,7 +341,7 @@ namespace VirtualFileSystem else hnd = dfdesc.Handle; - return hnd->Read((uint8_t *)buf, count); + return hnd->read((uint8_t *)buf, count); } ssize_t FileDescriptorTable::_write(int fd, const void *buf, @@ -342,8 +352,7 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } RefNode *hnd = nullptr; @@ -352,7 +361,7 @@ namespace VirtualFileSystem else hnd = dfdesc.Handle; - return hnd->Write((uint8_t *)buf, count); + return hnd->write((uint8_t *)buf, count); } int FileDescriptorTable::_close(int fd) @@ -363,15 +372,11 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } if (RemoveFileDescriptor(fd) < 0) - { - errno = EBADF; - return -1; - } + return -EBADF; /* If the file descriptor is a duplicate, we don't need to close the handle, @@ -417,8 +422,7 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } RefNode *hnd = nullptr; @@ -427,37 +431,34 @@ namespace VirtualFileSystem else hnd = dfdesc.Handle; - return hnd->Seek(offset, whence); + return hnd->seek(offset, whence); } int FileDescriptorTable::_stat(const char *pathname, struct stat *statbuf) { if (pathname == nullptr) - { - errno = EINVAL; - return -1; - } + return -EINVAL; - RefNode *file = vfs->Open(pathname, - thisProcess->CurrentWorkingDirectory); + RefNode *file = fs->Open(pathname, + thisProcess->CurrentWorkingDirectory); if (!file) { - error("Failed to open file %s: %d", - pathname, errno); - return -1; + error("Failed to open file %s", + pathname); + return -EIO; } Node *node = file->node; statbuf->st_dev = 0; /* FIXME: stub */ statbuf->st_ino = node->IndexNode; - statbuf->st_mode = node->Flags | node->Mode; + statbuf->st_mode = node->Type | node->Mode; statbuf->st_nlink = 0; /* FIXME: stub */ statbuf->st_uid = node->UserIdentifier; statbuf->st_gid = node->GroupIdentifier; statbuf->st_rdev = 0; /* FIXME: stub */ - statbuf->st_size = node->Length; + statbuf->st_size = node->Size; statbuf->st_blksize = 0; /* FIXME: stub */ statbuf->st_blocks = 0; /* FIXME: stub */ statbuf->st_attr = 0; /* FIXME: stub */ @@ -472,8 +473,7 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } RefNode *hnd = nullptr; @@ -485,12 +485,12 @@ namespace VirtualFileSystem Node *node = hnd->node; statbuf->st_dev = 0; /* FIXME: stub */ statbuf->st_ino = node->IndexNode; - statbuf->st_mode = node->Flags | node->Mode; + statbuf->st_mode = node->Type | node->Mode; statbuf->st_nlink = 0; /* FIXME: stub */ statbuf->st_uid = node->UserIdentifier; statbuf->st_gid = node->GroupIdentifier; statbuf->st_rdev = 0; /* FIXME: stub */ - statbuf->st_size = node->Length; + statbuf->st_size = node->Size; statbuf->st_blksize = 0; /* FIXME: stub */ statbuf->st_blocks = 0; /* FIXME: stub */ statbuf->st_attr = 0; /* FIXME: stub */ @@ -501,30 +501,27 @@ namespace VirtualFileSystem struct stat *statbuf) { if (pathname == nullptr) - { - errno = EINVAL; - return -1; - } + return -EINVAL; - RefNode *file = vfs->Open(pathname, - thisProcess->CurrentWorkingDirectory); + RefNode *file = fs->Open(pathname, + thisProcess->CurrentWorkingDirectory); if (!file) { - error("Failed to open file %s: %d", - pathname, errno); - return -1; + error("Failed to open file %s", + pathname); + return -EIO; } Node *node = file->node; statbuf->st_dev = 0; /* FIXME: stub */ statbuf->st_ino = node->IndexNode; - statbuf->st_mode = node->Flags | node->Mode; + statbuf->st_mode = node->Type | node->Mode; statbuf->st_nlink = 0; /* FIXME: stub */ statbuf->st_uid = node->UserIdentifier; statbuf->st_gid = node->GroupIdentifier; statbuf->st_rdev = 0; /* FIXME: stub */ - statbuf->st_size = node->Length; + statbuf->st_size = node->Size; statbuf->st_blksize = 0; /* FIXME: stub */ statbuf->st_blocks = 0; /* FIXME: stub */ statbuf->st_attr = 0; /* FIXME: stub */ @@ -539,16 +536,12 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } int newfd = this->GetFreeFileDescriptor(); if (newfd < 0) - { - errno = EMFILE; - return -1; - } + return -EMFILE; DupFildes new_dfd{}; if (fdesc.Descriptor != -1) @@ -577,15 +570,11 @@ namespace VirtualFileSystem if (fdesc.Descriptor < 0 && dfdesc.Descriptor < 0) { - errno = EBADF; - return -1; + return -EBADF; } if (newfd < 0) - { - errno = EBADF; - return -1; - } + return -EBADF; if (newfd == oldfd) return newfd; @@ -615,39 +604,39 @@ namespace VirtualFileSystem int FileDescriptorTable::_ioctl(int fd, unsigned long request, void *argp) { - struct winsize *ws = (struct winsize *)argp; - Video::ScreenBuffer *sb = Display->GetBuffer(0); - Video::FontInfo fi = Display->GetCurrentFont()->GetInfo(); - - switch (request) + Fildes fdesc = this->GetFileDescriptor(fd); + DupFildes dfdesc = this->GetDupFildes(fd); + if (fdesc.Descriptor < 0 && + dfdesc.Descriptor < 0) { - case TIOCGWINSZ: - fixme("TIOCGWINSZ: stub"); - ws->ws_xpixel = uint16_t(sb->Width); - ws->ws_ypixel = uint16_t(sb->Height); - ws->ws_col = uint16_t(sb->Width / fi.Width); - ws->ws_row = uint16_t(sb->Height / fi.Height); - break; - default: - fixme("Unknown request %#lx", request); - errno = ENOSYS; - return -1; + return -EBADF; } - return 0; + + RefNode *hnd = nullptr; + if (fdesc.Descriptor != -1) + hnd = fdesc.Handle; + else + hnd = dfdesc.Handle; + + return hnd->ioctl(request, argp); } FileDescriptorTable::FileDescriptorTable(void *Owner) { - this->fdDir = vfs->Create("fd", VirtualFileSystem::NodeFlags::DIRECTORY, - ((Tasking::PCB *)Owner)->ProcessDirectory); + debug("+ %#lx", this); + this->fdDir = fs->Create("fd", vfs::NodeType::DIRECTORY, + ((Tasking::PCB *)Owner)->ProcessDirectory); } FileDescriptorTable::~FileDescriptorTable() { - foreach (auto var in FileDescriptors) + debug("- %#lx", this); + foreach (auto fd in FileDescriptors) { - this->RemoveFileDescriptor(var.Descriptor); - delete var.Handle; + debug("Removing fd: %d(%#lx)", + fd.Descriptor, fd); + this->RemoveFileDescriptor(fd.Descriptor); + delete fd.Handle; } } } diff --git a/storage/filesystem.cpp b/storage/filesystem.cpp new file mode 100644 index 00000000..fc679803 --- /dev/null +++ b/storage/filesystem.cpp @@ -0,0 +1,402 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include + +#include "../kernel.h" + +// show debug messages +// #define DEBUG_FILESYSTEM 1 + +#ifdef DEBUG_FILESYSTEM +#define vfsdbg(m, ...) debug(m, ##__VA_ARGS__) +#else +#define vfsdbg(m, ...) +#endif + +namespace vfs +{ + Node *Virtual::GetNodeFromPath_Unsafe(const char *Path, Node *Parent) + { + vfsdbg("GetNodeFromPath( Path: \"%s\" Parent: \"%s\" )", + Path, Parent ? Parent->Name : "(null)"); + + if (strcmp(Path, "/") == 0) + return FileSystemRoot->Children[0]; // 0 - filesystem root + + if (strcmp(Path, ".") == 0) + return Parent; + + if (strcmp(Path, "..") == 0) + { + if (Parent) + { + if (Parent->Parent) + return Parent->Parent; + else + return Parent; + } + else + return nullptr; + } + + Node *ReturnNode = Parent; + bool IsAbsolutePath = cwk_path_is_absolute(Path); + + if (!ReturnNode) + ReturnNode = FileSystemRoot->Children[0]; // 0 - filesystem root + + if (IsAbsolutePath) + ReturnNode = FileSystemRoot->Children[0]; // 0 - filesystem root + + cwk_segment segment; + if (unlikely(!cwk_path_get_first_segment(Path, &segment))) + { + error("Path doesn't have any segments."); + return nullptr; + } + + do + { + char *SegmentName = new char[segment.end - segment.begin + 1]; + memcpy(SegmentName, segment.begin, segment.end - segment.begin); + vfsdbg("GetNodeFromPath()->SegmentName: \"%s\"", SegmentName); + GetNodeFromPathNextParent: + foreach (auto Child in ReturnNode->Children) + { + vfsdbg("comparing \"%s\" with \"%s\"", + Child->Name, SegmentName); + if (strcmp(Child->Name, SegmentName) == 0) + { + ReturnNode = Child; + goto GetNodeFromPathNextParent; + } + } + delete[] SegmentName; + } while (cwk_path_get_next_segment(&segment)); + + const char *basename; + cwk_path_get_basename(Path, &basename, nullptr); + vfsdbg("BaseName: \"%s\" NodeName: \"%s\"", + basename, ReturnNode->Name); + + if (strcmp(basename, ReturnNode->Name) == 0) + { + vfsdbg("GetNodeFromPath()->\"%s\"", ReturnNode->Name); + return ReturnNode; + } + + vfsdbg("GetNodeFromPath()->\"(null)\""); + return nullptr; + } + + Node *Virtual::GetNodeFromPath(const char *Path, Node *Parent) + { + SmartLock(VirtualLock); + return GetNodeFromPath_Unsafe(Path, Parent); + } + + bool Virtual::PathIsRelative(const char *Path) + { + vfsdbg("PathIsRelative( Path: \"%s\" )", Path); + bool IsRelative = cwk_path_is_relative(Path); + vfsdbg("PathIsRelative()->\"%s\"", + IsRelative ? "true" : "false"); + return IsRelative; + } + + Node *Virtual::GetParent(const char *Path, Node *Parent) + { + vfsdbg("GetParent( Path: \"%s\" Parent: \"%s\" )", + Path, Parent ? Parent->Name : "(nil)"); + + if (Parent) + { + vfsdbg("GetParent()->\"%s\"", Parent->Name); + return Parent; + } + + Parent = FileSystemRoot->Children[0]; + + size_t length; + cwk_path_get_root(Path, &length); + if (length > 0) + { + foreach (auto Child in FileSystemRoot->Children) + { + if (strcmp(Child->Name, Path) == 0) + { + Parent = Child; + break; + } + } + } + + vfsdbg("GetParent()->\"%s\"", ParentNode->Name); + return Parent; + } + + const char *Virtual::NormalizePath(const char *Path, Node *Parent) + { + assert(Parent != nullptr); + + vfsdbg("NormalizePath( Path: \"%s\" Parent: \"%s\" )", + Path, Parent->Name); + + size_t PathSize = strlen((char *)Path) + 1; + char *NormalizedPath = new char[PathSize]; + + { + Memory::SmartHeap sh(PathSize); + memcpy(sh, (char *)Path, PathSize); + cwk_path_normalize(sh, NormalizedPath, PathSize); + } + + const char *FinalPath; + if (cwk_path_is_relative(NormalizedPath)) + { + size_t PathSize = cwk_path_join(Parent->FullPath, + NormalizedPath, + nullptr, 0); + + FinalPath = new char[PathSize + 1]; + cwk_path_join(Parent->FullPath, NormalizedPath, + (char *)FinalPath, PathSize + 1); + + delete[] NormalizedPath; + } + else + FinalPath = NormalizedPath; + + vfsdbg("NormalizePath()->\"%s\"", FinalPath); + return FinalPath; + } + + bool Virtual::PathExists(const char *Path, Node *Parent) + { + if (isempty((char *)Path)) + { + vfsdbg("PathExists()->PathIsEmpty"); + return false; + } + + if (Parent == nullptr) + Parent = FileSystemRoot; + + vfsdbg("PathExists( Path: \"%s\" Parent: \"%s\" )", + Path, Parent->Name); + + const char *CleanPath = NormalizePath(Path, Parent); + bool ret = GetNodeFromPath(CleanPath, Parent) != nullptr; + delete[] CleanPath; + vfsdbg("PathExists()->\"%s\"", + ret ? "true" : "false"); + return ret; + } + + Node *Virtual::Create(const char *Path, NodeType Type, Node *Parent) + { + if (isempty((char *)Path)) + return nullptr; + + SmartLock(VirtualLock); + Node *RootNode = FileSystemRoot->Children[0]; + Node *CurrentParent = this->GetParent(Path, Parent); + vfsdbg("Virtual::Create( Path: \"%s\" Parent: \"%s\" )", + Path, Parent ? Parent->Name : CurrentParent->Name); + + const char *CleanPath = this->NormalizePath(Path, CurrentParent); + vfsdbg("CleanPath: \"%s\"", CleanPath); + + VirtualLock.Unlock(); + if (PathExists(CleanPath, CurrentParent)) + { + error("Path \"%s\" already exists.", CleanPath); + goto CreatePathError; + } + VirtualLock.Lock(__FUNCTION__); + + cwk_segment segment; + if (!cwk_path_get_first_segment(CleanPath, &segment)) + { + error("Path doesn't have any segments."); + goto CreatePathError; + } + + do + { + char *SegmentName = new char[segment.end - segment.begin + 1]; + memcpy(SegmentName, segment.begin, segment.end - segment.begin); + vfsdbg("SegmentName: \"%s\"", SegmentName); + + auto GetChild = [](const char *Name, Node *Parent) + { + vfsdbg("GetChild( Name: \"%s\" Parent: \"%s\" )", + Name, Parent->Name); + + if (!Parent) + { + vfsdbg("GetChild()->nullptr"); + return (Node *)nullptr; + } + + foreach (auto Child in Parent->Children) + { + if (strcmp(Child->Name, Name) == 0) + { + vfsdbg("GetChild()->\"%s\"", Child->Name); + return Child; + } + } + + vfsdbg("GetChild()->nullptr (not found)"); + return (Node *)nullptr; + }; + + if (Parent) + { + if (GetChild(SegmentName, RootNode) != nullptr) + { + RootNode = GetChild(SegmentName, RootNode); + delete[] SegmentName; + continue; + } + } + + if (GetChild(SegmentName, CurrentParent) == nullptr) + { + Node *NewNode = new Node(CurrentParent, + SegmentName, + NodeType::DIRECTORY); + + CurrentParent = NewNode; + CurrentParent->Type = Type; + CurrentParent->FullPath = CleanPath; + } + else + { + CurrentParent = GetChild(SegmentName, CurrentParent); + } + + delete[] SegmentName; + } while (cwk_path_get_next_segment(&segment)); + + vfsdbg("Virtual::Create()->\"%s\"", CurrentParent->Name); +#ifdef DEBUG + VirtualLock.Unlock(); + debug("Path created: \"%s\"", + CurrentParent->FullPath); + VirtualLock.Lock(__FUNCTION__); +#endif + return CurrentParent; + + CreatePathError: + delete[] CleanPath; + vfsdbg("Virtual::Create()->nullptr"); + return nullptr; + } + + int Virtual::Delete(const char *Path, bool Recursive, Node *Parent) + { + vfsdbg("Virtual::Delete( Path: \"%s\" Parent: \"%s\" )", + Path, Parent ? Parent->Name : "(null)"); + + if (isempty((char *)Path)) + return -EINVAL; + + if (Parent == nullptr) + Parent = FileSystemRoot; + + const char *CleanPath = this->NormalizePath(Path, Parent); + vfsdbg("CleanPath: \"%s\"", CleanPath); + + if (!PathExists(CleanPath, Parent)) + { + vfsdbg("Path \"%s\" doesn't exist.", CleanPath); + delete[] CleanPath; + return -ENOENT; + } + + Node *NodeToDelete = GetNodeFromPath(CleanPath, Parent); + delete[] CleanPath; + return NodeToDelete->Delete(Recursive); + } + + int Virtual::Delete(Node *Path, bool Recursive, Node *Parent) + { + return Delete(Path->FullPath, Recursive, Parent); + } + + RefNode *Virtual::Open(const char *Path, Node *Parent) + { + vfsdbg("Opening \"%s\" with parent \"%s\"", + Path, Parent ? Parent->Name : "(null)"); + + if (strcmp(Path, "/") == 0) + return FileSystemRoot->CreateReference(); + + if (!Parent) + Parent = FileSystemRoot->Children[0]; + + if (strcmp(Path, ".") == 0) + return Parent->CreateReference(); + + if (strcmp(Path, "..") == 0) + { + if (Parent->Parent) + return Parent->Parent->CreateReference(); + else + return Parent->CreateReference(); + } + + Node *CurrentParent = this->GetParent(Path, Parent); + const char *CleanPath = NormalizePath(Path, CurrentParent); + + if (PathExists(CleanPath, CurrentParent)) + { + Node *node = GetNodeFromPath(CleanPath, CurrentParent); + if (node) + { + delete[] CleanPath; + /* TODO: Check if dir or file? */ + return node->CreateReference(); + } + } + + return nullptr; + } + + Virtual::Virtual() + { + SmartLock(VirtualLock); + trace("Initializing virtual file system..."); + FileSystemRoot = new Node(nullptr, "", NodeType::MOUNTPOINT); + FileSystemRoot->vFS = this; + } + + Virtual::~Virtual() + { + SmartLock(VirtualLock); + stub; + /* TODO: sync, cache */ + } +} diff --git a/storage/fs/fat32.cpp b/storage/fs/fat32.cpp new file mode 100644 index 00000000..2223d29d --- /dev/null +++ b/storage/fs/fat32.cpp @@ -0,0 +1,27 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +#include "../../kernel.h" + +namespace vfs +{ +} diff --git a/storage/fs/null.cpp b/storage/fs/null.cpp new file mode 100644 index 00000000..0c062f6b --- /dev/null +++ b/storage/fs/null.cpp @@ -0,0 +1,37 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +#include "../../kernel.h" + +namespace vfs +{ + size_t NullDevice::read(uint8_t *Buffer, size_t Size, off_t Offset) + { + return Size; + } + + size_t NullDevice::write(uint8_t *Buffer, size_t Size, off_t Offset) + { + return Size; + } + + NullDevice::NullDevice() : Node(DevFS, "null", CHARDEVICE) {} + NullDevice::~NullDevice() {} +} diff --git a/storage/fs/ptmx.cpp b/storage/fs/ptmx.cpp new file mode 100644 index 00000000..8f7fc4b4 --- /dev/null +++ b/storage/fs/ptmx.cpp @@ -0,0 +1,49 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include + +#include "../../kernel.h" + +namespace vfs +{ + size_t PTMXDevice::read(uint8_t *Buffer, size_t Size, off_t Offset) + { + if (Size <= 0) + return 0; + + memset(Buffer, 0, Size); + return Size; + } + + size_t PTMXDevice::write(uint8_t *Buffer, size_t Size, off_t Offset) + { + return Size; + } + + PTMXDevice::PTMXDevice() : Node(DevFS, "null", CHARDEVICE) + { + pts = new Node(DevFS, "pts", DIRECTORY); + } + + PTMXDevice::~PTMXDevice() + { + delete pts; + } +} diff --git a/storage/fs/random.cpp b/storage/fs/random.cpp new file mode 100644 index 00000000..be170b25 --- /dev/null +++ b/storage/fs/random.cpp @@ -0,0 +1,44 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include + +#include "../../kernel.h" + +namespace vfs +{ + size_t RandomDevice::read(uint8_t *Buffer, size_t Size, off_t Offset) + { + if (Size <= 0) + return 0; + + uint64_t *buf = (uint64_t *)Buffer; + for (size_t i = 0; i < Size / sizeof(uint64_t); i++) + buf[i] = Random::rand64(); + return Size; + } + + size_t RandomDevice::write(uint8_t *Buffer, size_t Size, off_t Offset) + { + return Size; + } + + RandomDevice::RandomDevice() : Node(DevFS, "random", CHARDEVICE) {} + RandomDevice::~RandomDevice() {} +} diff --git a/storage/fs/root.cpp b/storage/fs/root.cpp new file mode 100644 index 00000000..435acd7c --- /dev/null +++ b/storage/fs/root.cpp @@ -0,0 +1,32 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include "../../kernel.h" + +namespace vfs +{ + vfsRoot::vfsRoot(const char *Name, Virtual *vfs_ctx) + : Node(nullptr, + Name, + MOUNTPOINT) + { + this->vFS = fs; + vfs_ctx->GetRootNode()->Children.push_back(this); + } +} diff --git a/storage/fs/tty.cpp b/storage/fs/tty.cpp new file mode 100644 index 00000000..c1eac3c3 --- /dev/null +++ b/storage/fs/tty.cpp @@ -0,0 +1,61 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include +#include + +#include "../../kernel.h" + +namespace vfs +{ + size_t TTYDevice::write(uint8_t *Buffer, size_t Size, off_t Offset) + { + for (size_t i = 0; i < Size; i++) + putchar(((char *)Buffer)[i]); + + Display->SetBuffer(0); /* FIXME: stub */ + return Size; + } + + int TTYDevice::ioctl(unsigned long Request, void *Argp) + { + switch (Request) + { + case TIOCGWINSZ: + { + struct winsize *ws = (struct winsize *)Argp; + Video::ScreenBuffer *sb = Display->GetBuffer(0); + Video::FontInfo fi = Display->GetCurrentFont()->GetInfo(); + + fixme("TIOCGWINSZ: stub"); + ws->ws_xpixel = uint16_t(sb->Width); + ws->ws_ypixel = uint16_t(sb->Height); + ws->ws_col = uint16_t(sb->Width / fi.Width); + ws->ws_row = uint16_t(sb->Height / fi.Height); + break; + } + default: + fixme("Unknown request %#lx", Request); + return -EINVAL; + } + return 0; + } + + TTYDevice::TTYDevice() : Node(DevFS, "tty", CHARDEVICE) {} + TTYDevice::~TTYDevice() {} +} diff --git a/storage/fs/ustar.cpp b/storage/fs/ustar.cpp new file mode 100644 index 00000000..1a7131e6 --- /dev/null +++ b/storage/fs/ustar.cpp @@ -0,0 +1,178 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +#include "../../kernel.h" + +namespace vfs +{ + size_t USTARNode::read(uint8_t *Buffer, + size_t Size, + off_t Offset) + { + if (Size <= 0) + Size = this->Size; + + if (Offset > this->Size) + return 0; + + if ((this->Size - Offset) == 0) + return 0; /* EOF */ + + if (Offset + (off_t)Size > this->Size) + Size = this->Size; + + memcpy(Buffer, (uint8_t *)(this->Address + Offset), Size); + return Size; + } + + USTARNode::USTARNode(uintptr_t Address, + const char *Name, + NodeType Type, + Virtual *vfs_ctx) + : Node(nullptr, + Name, + Type, + true, + vfs_ctx, + nullptr), + Address(Address) + { + } + + USTARNode::~USTARNode() {} + + bool USTAR::TestArchive(uintptr_t Address) + { + if (!Memory::Virtual().Check((void *)Address)) + { + error("Address %#lx is not mapped!", Address); + return false; + } + + FileHeader *header = (FileHeader *)Address; + if (memcmp(header->signature, "ustar", 5) != 0) + { + error("ustar signature invalid!"); + return false; + } + return true; + } + + void USTAR::ReadArchive(uintptr_t Address, Virtual *vfs_ctx) + { + trace("Initializing USTAR with address %#lx", Address); + + if (!this->TestArchive(Address)) + return; /* Check whether the archive is deflated */ + + FileHeader *header = (FileHeader *)Address; + + debug("USTAR signature valid! Name:%s Signature:%s Mode:%d Size:%lu", + header->name, header->signature, + string2int(header->mode), header->size); + + for (size_t i = 0;; i++) + { + if (memcmp(header->signature, "ustar", 5) != 0) + break; + + memmove(header->name, + header->name + 1, + strlen(header->name)); + + if (header->name[strlen(header->name) - 1] == '/') + { + debug("Removing trailing slash from %s", header->name); + header->name[strlen(header->name) - 1] = 0; + } + + // if (!isempty((char *)header->name)) + // KPrint("Adding file \e88AACC%s\eCCCCCC (\e88AACC%lu \eCCCCCCbytes)", header->name, size); + // else + // goto NextFileAddress; + + size_t size = getsize(header->size); + Node *node; + NodeType type = NODE_TYPE_NONE; + if (isempty((char *)header->name)) + goto NextFileAddress; + + switch (header->typeflag[0]) + { + case REGULAR_FILE: + type = NodeType::FILE; + break; + case SYMLINK: + type = NodeType::SYMLINK; + break; + case DIRECTORY: + type = NodeType::DIRECTORY; + break; + case CHARDEV: + type = NodeType::CHARDEVICE; + break; + case BLOCKDEV: + type = NodeType::BLOCKDEVICE; + break; + default: + warn("Unknown type: %d", header->typeflag[0]); + break; + } + + node = new USTARNode((Address + 512), header->name, + type, vfs_ctx); + + debug("%s %d KiB, Type:%c", header->name, + TO_KiB(size), header->typeflag[0]); + node->Mode = string2int(header->mode); + node->Size = size; + node->GroupIdentifier = getsize(header->gid); + node->UserIdentifier = getsize(header->uid); + node->DeviceMajor = getsize(header->dev_maj); + node->DeviceMinor = getsize(header->dev_min); + + node->AccessTime = getsize(header->mtime); + node->ModifyTime = getsize(header->mtime); + node->ChangeTime = getsize(header->mtime); + node->IndexNode = i; + + if (type == NodeType::SYMLINK) + { + node->Symlink = new char[strlen(header->link) + 1]; + strncpy((char *)node->Symlink, + header->link, + strlen(header->link)); + } + + NextFileAddress: + Address += ((size / 512) + 1) * 512; + if (size % 512) + Address += 512; + + header = (FileHeader *)Address; + } + } + + USTAR::USTAR() {} + + USTAR::~USTAR() {} +} diff --git a/storage/fs/zero.cpp b/storage/fs/zero.cpp new file mode 100644 index 00000000..c8168d0f --- /dev/null +++ b/storage/fs/zero.cpp @@ -0,0 +1,43 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +#include "../../kernel.h" + +using namespace vfs; + +namespace vfs +{ + size_t ZeroDevice::read(uint8_t *Buffer, size_t Size, off_t Offset) + { + if (Size <= 0) + return 0; + + memset(Buffer, 0, Size); + return Size; + } + + size_t ZeroDevice::write(uint8_t *Buffer, size_t Size, off_t Offset) + { + return Size; + } + + ZeroDevice::ZeroDevice() : Node(DevFS, "zero", CHARDEVICE) {} + ZeroDevice::~ZeroDevice() {} +} diff --git a/FileSystem/Kernel_IO.cpp b/storage/kernel_io.cpp similarity index 65% rename from FileSystem/Kernel_IO.cpp rename to storage/kernel_io.cpp index e787f127..c9bf0ce5 100644 --- a/FileSystem/Kernel_IO.cpp +++ b/storage/kernel_io.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -21,7 +21,7 @@ #include "../kernel.h" using Tasking::PCB; -using VirtualFileSystem::FileDescriptorTable; +using vfs::FileDescriptorTable; static bool CheckForScheduler() { @@ -33,10 +33,7 @@ static bool CheckForScheduler() int fopen(const char *pathname, const char *mode) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -47,10 +44,7 @@ int fopen(const char *pathname, const char *mode) int creat(const char *pathname, mode_t mode) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -61,10 +55,7 @@ int creat(const char *pathname, mode_t mode) ssize_t fread(int fd, void *buf, size_t count) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -75,10 +66,7 @@ ssize_t fread(int fd, void *buf, size_t count) ssize_t fwrite(int fd, const void *buf, size_t count) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -89,10 +77,7 @@ ssize_t fwrite(int fd, const void *buf, size_t count) int fclose(int fd) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -103,10 +88,7 @@ int fclose(int fd) off_t lseek(int fd, off_t offset, int whence) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -117,10 +99,7 @@ off_t lseek(int fd, off_t offset, int whence) int stat(const char *pathname, struct stat *statbuf) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -131,10 +110,7 @@ int stat(const char *pathname, struct stat *statbuf) int fstat(int fd, struct stat *statbuf) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; @@ -145,10 +121,7 @@ int fstat(int fd, struct stat *statbuf) int lstat(const char *pathname, struct stat *statbuf) { if (!CheckForScheduler()) - { - errno = ENOSYS; - return -1; - } + return -ENOSYS; PCB *pcb = thisProcess; FileDescriptorTable *fdt = pcb->FileDescriptors; diff --git a/storage/node.cpp b/storage/node.cpp new file mode 100644 index 00000000..5e5e8884 --- /dev/null +++ b/storage/node.cpp @@ -0,0 +1,263 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include +#include + +namespace vfs +{ + int Node::open(int Flags, mode_t Mode) + { + debug("Operation not handled"); + return -ENXIO; + } + + int Node::close() + { + debug("Operation not handled"); + return -ENXIO; + } + + size_t Node::read(uint8_t *Buffer, size_t Size, off_t Offset) + { + debug("Operation not handled"); + return -ENXIO; + } + + size_t Node::write(uint8_t *Buffer, size_t Size, off_t Offset) + { + debug("Operation not handled"); + return -ENXIO; + } + + int Node::ioctl(unsigned long Request, void *Argp) + { + debug("Operation not handled"); + return -ENODEV; + } + + RefNode *Node::CreateReference() + { + SmartLock(NodeLock); + RefNode *ref = new RefNode(this); + References.push_back(ref); + debug("Created reference %#lx for node %#lx", ref, this); + return ref; + } + + void Node::RemoveReference(RefNode *Reference) + { + SmartLock(NodeLock); + debug("Removing reference %#lx for node %#lx", Reference, this); + References.erase(std::find(References.begin(), + References.end(), + Reference)); + } + + Node::Node(Node *Parent, const char *Name, NodeType Type, + bool NoParent, Virtual *fs, int *Err) + { + assert(Name != nullptr); + assert(strlen(Name) != 0); + assert((NoParent == false && + fs == nullptr) || + (NoParent == true && + fs != nullptr)); + + if (Err != nullptr) + *Err = 0; + + this->Type = Type; + + auto GetChild = [](const char *Name, Node *Parent) + { + if (!Parent) + return (Node *)nullptr; + + foreach (auto Child in Parent->Children) + { + if (strcmp(Child->Name, Name) == 0) + return Child; + } + + return (Node *)nullptr; + }; + + auto CreateWithParent = [this](const char *Name, Node *Parent) + { + assert(Parent->vFS != nullptr); + assert(Parent->Type == DIRECTORY || + Parent->Type == MOUNTPOINT); + + this->vFS = Parent->vFS; + this->Parent = Parent; + + this->Name = new char[strlen(Name) + 1]; + strcpy((char *)this->Name, Name); + + this->FullPath = new char[strlen(Parent->FullPath) + + strlen(this->Name) + 2]; + strcpy((char *)this->FullPath, Parent->FullPath); + if (strcmp(this->FullPath, "/") != 0) + strcat((char *)this->FullPath, "/"); + strcat((char *)this->FullPath, this->Name); + + this->Parent->Children.push_back(this); + }; + + if (Parent) + CreateWithParent(Name, Parent); + else if (NoParent) + { + const char *Path = Name; + + Node *RootNode = fs->FileSystemRoot->Children[0]; + Node *CurrentParent = fs->GetParent(Path, Parent); + + if (fs->PathExists(Path, CurrentParent)) + { + debug("Path \"%s\" already exists.", Path); + delete[] Path; + if (Err != nullptr) + *Err = -EEXIST; + delete this; + return; + } + + const char *CleanPath = fs->NormalizePath(Path, CurrentParent); + + cwk_segment segment; + if (!cwk_path_get_first_segment(CleanPath, &segment)) + { + debug("Path doesn't have any segments."); + delete[] CleanPath; + if (Err != nullptr) + *Err = -EINVAL; + delete this; + return; + } + + cwk_segment last_segment; + cwk_path_get_last_segment(CleanPath, &last_segment); + + do + { + char *SegmentName = new char[segment.end - segment.begin + 1]; + memcpy(SegmentName, segment.begin, segment.end - segment.begin); + + if (Parent) + { + if (GetChild(SegmentName, RootNode) != nullptr) + { + RootNode = GetChild(SegmentName, RootNode); + delete[] SegmentName; + continue; + } + } + + if (GetChild(SegmentName, CurrentParent) == nullptr) + { + if (segment.begin == last_segment.begin) + { + CreateWithParent(SegmentName, CurrentParent); + delete[] SegmentName; + break; /* This is the last segment anyway... */ + } + + CurrentParent = new Node(CurrentParent, + SegmentName, + Type); + } + else + { + CurrentParent = GetChild(SegmentName, CurrentParent); + } + + delete[] SegmentName; + } while (cwk_path_get_next_segment(&segment)); + } + else + { + this->Name = new char[strlen(Name) + 1]; + strcpy((char *)this->Name, Name); + this->FullPath = Name; + + trace("Node %s(%#lx) has no parent", + this->Name, this); + } + } + + int Node::Delete(bool Recursive) + { + if (this->References.size() != 0) + { + debug("Node %s(%#lx) has %ld references", + this->FullPath, this, + this->References.size()); + return -EBUSY; + } + + if (this->Type == MOUNTPOINT || + this->Type == DIRECTORY) + { + if (this->Children.size() != 0) + { + if (!Recursive) + { + debug("Node %s(%#lx) has %ld children", + this->FullPath, this, + this->Children.size()); + return -ENOTEMPTY; + } + + for (auto Child : this->Children) + { + int ret = Child->Delete(Recursive); + + if (ret < 0) + { + debug("Failed to delete child %s(%#lx)", + Child->FullPath, Child); + return ret; + } + } + } + } + + delete this; + return 0; + } + + Node::~Node() + { + debug("Destroyed node %#lx", this); + assert(this->Children.size() == 0); + + if (this->Parent) + { + this->Parent->Children.erase(std::find(this->Parent->Children.begin(), + this->Parent->Children.end(), + this)); + } + + delete[] this->Name; + if (this->Parent) + delete[] this->FullPath; + if (this->Symlink) + delete[] this->Symlink; + } +} diff --git a/storage/ref_node.cpp b/storage/ref_node.cpp new file mode 100644 index 00000000..7580dd3b --- /dev/null +++ b/storage/ref_node.cpp @@ -0,0 +1,158 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#ifdef DEBUG +const char *SeekStrings[] = + {"SEEK_SET", + "SEEK_CUR", + "SEEK_END"}; +#endif + +namespace vfs +{ + size_t RefNode::read(uint8_t *Buffer, size_t Size) + { + if (this->SymlinkTo) + return this->SymlinkTo->read(Buffer, Size); + + return this->node->read(Buffer, Size, this->FileOffset.load()); + } + + size_t RefNode::write(uint8_t *Buffer, size_t Size) + { + if (this->SymlinkTo) + return this->SymlinkTo->write(Buffer, Size); + + return this->node->write(Buffer, Size, this->FileOffset.load()); + } + + off_t RefNode::seek(off_t Offset, int Whence) + { + if (this->SymlinkTo) + return this->SymlinkTo->seek(Offset, Whence); + + // debug("Current offset is %d", this->Offset.load()); + switch (Whence) + { + case SEEK_SET: + { + if (Offset > this->FileSize) + return -EINVAL; + + if (Offset < 0) + { + fixme("Negative offset %d is not implemented", Offset); + Offset = 0; + } + + if (Offset > this->FileSize) + { + fixme("Offset %d is bigger than file size %d", + Offset, this->FileSize); + Offset = this->FileSize; + } + + this->FileOffset.store(Offset); + break; + } + case SEEK_CUR: + { + off_t NewOffset = off_t(this->FileOffset.load()) + Offset; + if (NewOffset > this->FileSize || + NewOffset < 0) + { + return -EINVAL; + } + + this->FileOffset.store(NewOffset); + break; + } + case SEEK_END: + { + off_t NewOffset = this->FileSize + Offset; + if (NewOffset > this->FileSize || + NewOffset < 0) + { + return -EINVAL; + } + + this->FileOffset.store(NewOffset); + break; + } + default: + { + error("Invalid whence!"); + return -EINVAL; + } + } + + off_t RetOffset = off_t(this->FileOffset.load()); + // debug("( %d %ld %s[%d] ) -> %d", + // Offset, this->Offset.load(), + // SeekStrings[Whence], Whence, + // RetOffset); + return RetOffset; + } + + int RefNode::ioctl(unsigned long Request, void *Argp) + { + if (this->SymlinkTo) + return this->SymlinkTo->ioctl(Request, Argp); + + return this->node->ioctl(Request, Argp); + } + + RefNode::RefNode(Node *node) + { + this->node = node; + this->FileSize = node->Size; + if (this->node->Type == SYMLINK) + { + if (!this->node->SymlinkTarget) + { + this->node->SymlinkTarget = + node->vFS->GetNodeFromPath(this->node->Symlink); + } + + if (!this->node->SymlinkTarget) + { + error("Symlink target %s not found!", + this->node->Symlink); + return; + } + + /* not standard but useful in kernel-space */ + this->node->Size = this->node->SymlinkTarget->Size; + this->SymlinkTo = this->node->SymlinkTarget->CreateReference(); + } + + debug("Created reference node for %s [%#lx]", + this->node->FullPath, (uintptr_t)this); + } + + RefNode::~RefNode() + { + if (this->SymlinkTo) + this->node->SymlinkTarget->RemoveReference(this); + this->node->RemoveReference(this); + + debug("Destroyed reference node for %s [%#lx]", + this->node->FullPath, (uintptr_t)this); + } +} diff --git a/syscalls.h b/syscalls.h index c68b7759..fed4f958 100644 --- a/syscalls.h +++ b/syscalls.h @@ -1,86 +1,55 @@ /* - BSD 3-Clause License + BSD 3-Clause License - Copyright (c) 2023, EnderIce2 - All rights reserved. + Copyright (c) 2023, EnderIce2 + All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FENNIX_KERNEL_SYSCALLS_LIST_H__ #define __FENNIX_KERNEL_SYSCALLS_LIST_H__ -#include +/* mmap */ -#define LTS_SET_GS 0x1 -#define LTS_SET_FS 0x2 -#define LTS_GET_FS 0x3 -#define LTS_GET_GS 0x4 -#define LTS_SET_CPUID 0x5 -#define LTS_GET_CPUID 0x6 +#define sc_PROT_NONE 0 +#define sc_PROT_READ 1 +#define sc_PROT_WRITE 2 +#define sc_PROT_EXEC 4 -typedef enum -{ - MAP_PRESENT = 1 << 0, - MAP_WRITABLE = 1 << 1, - MAP_USER = 1 << 2, -} MemoryMapFlags; +#define sc_MAP_SHARED 1 +#define sc_MAP_PRIVATE 2 +#define sc_MAP_FIXED 4 +#define sc_MAP_ANONYMOUS 8 -typedef enum -{ - SYSCALL_SEEK_SET = 0, - SYSCALL_SEEK_CUR = 1, - SYSCALL_SEEK_END = 2 -} FileSeekMode; +/* lseek */ -typedef enum -{ - /** - * Print a string to the screen using KPrint - * - * The uptime is prepended to the - * string before printing. - * - * Arguments: - * Arg1 - String to print - * Arg2 - Length of string - */ - KCTL_PRINT = 0, - - /** - * Get the page size - */ - KCTL_GET_PAGE_SIZE, - - /** - * Check whether the current - * thread is critical - */ - KCTL_IS_CRITICAL, -} KCtl; +#define sc_SEEK_SET 0 +#define sc_SEEK_CUR 1 +#define sc_SEEK_END 2 /** * Enumeration of all the native syscalls @@ -88,387 +57,85 @@ typedef enum */ typedef enum { - /** - * - * Basic syscalls - * - */ - /** * This syscall is used to exit the current * process with the provided exit code. * + * @fn void exit(int status); + * * @param Code The exit code * @return This syscall does not return * * @note No permissions are required to call * this syscall */ - sys_Exit = 0, + sc_exit = 0, /** + * Map pages of memory * - * Memory syscalls - * + * @fn void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); */ + sc_mmap, /** - * This syscall is used to request a specific - * number of pages of memory from the kernel. + * Unmap pages of memory * - * @param Count The number of pages to request - * @return The address of the first page of - * memory that was requested - * - * @note No permissions are required to call - * this syscall + * @fn int munmap(void *addr, size_t len); */ - sys_RequestPages, + sc_munmap, /** - * This syscall is used to free a specific - * number of pages of memory that were - * previously requested. + * Change the protection of a page of memory * - * @param Address The address of the first - * page of memory to free - * @param Count The number of pages to free - * @return 0 on success, errno on failure - * - * @note No permissions are required to call - * this syscall + * @fn int mprotect(void *addr, size_t len, int prot); */ - sys_FreePages, + sc_mprotect, /** - * This syscall is used to detach a specific - * memory address from the current process. - * This means that the address will no longer - * be freed when the process exits. + * Open a file * - * @param Address The address to detach - * @return 0 on success, errno on failure - * - * @note The process must be trusted by the - * kernel to call this syscall + * @fn int open(const char *path, int oflag, ... ); */ - sys_DetachAddress, + sc_open, /** - * This syscall is used to map a specific - * memory address to the current process. + * Close a file descriptor * - * @param VirtualAddress The virtual address - * to map - * @param PhysicalAddress The physical address - * to map - * @param Size The size of the memory region - * to map - * @param Flags The flags to use when mapping - * the memory region (see MemoryMapFlags) - * @return 0 on success, errno on failure - * - * @note The process must be trusted by the - * kernel to call this syscall + * @fn int close(int fildes); */ - sys_MemoryMap, + sc_close, /** - * This syscall is used to unmap a specific - * memory address from the current process. + * Read from a file descriptor * - * @param VirtualAddress The virtual address - * to unmap - * @param Size The size of the memory region - * to unmap - * @return 0 on success, errno on failure - * - * @note The process must be trusted by the - * kernel to call this syscall + * @fn ssize_t read(int fildes, void *buf, size_t nbyte); */ - sys_MemoryUnmap, + sc_read, /** + * Write to a file descriptor * - * Kernel Control syscalls - * + * @fn ssize_t write(int fildes, const void *buf, size_t nbyte); */ + sc_write, /** - * Kernel Control + * Seek to a position in a file descriptor * - * This syscall is used to control certain - * aspects of the kernel or get information - * about it. - * - * @param Command The command to execute - * @param Arg1 The first argument - * @param Arg2 The second argument - * @param Arg3 The third argument - * @param Arg4 The fourth argument - * @return The result of the command, or - * errno on failure - * - * @note No permissions are required to - * call this syscall + * @fn off_t lseek(int fildes, off_t offset, int whence); */ - sys_KernelCTL, + sc_lseek, /** - * - * File syscalls - * + * Create a new process + * + * @fn pid_t fork(void); */ - - /** - * This syscall is used to open a file with - * the provided path and flags. - * - * @param Path The path to the file to open - * @param Flags The flags to use when opening - * the file - * @param Mode The mode to use when opening - * the file - * @return The file descriptor of the opened - * file, or errno on failure - * - * @note No permissions are required to - * call this syscall - */ - sys_FileOpen, - - /** - * This syscall is used to close a file - * that was previously opened. - * - * @param FileDescriptor The file descriptor - * of the file to close - * - * @note No permissions are required to - * call this syscall - */ - sys_FileClose, - - /** - * This syscall is used to read a specific - * number of bytes from a file at a specific - * offset. - * - * @param FileDescriptor The file descriptor - * of the file to read from - * @param Buffer The buffer to read into - * @param Count The number of bytes to read - * @return The number of bytes read, or - * errno on failure - * - * @note No permissions are required to - * call this syscall - */ - sys_FileRead, - - /** - * This syscall is used to write a specific - * number of bytes to a file at a specific - * offset. - * - * @param FileDescriptor The file descriptor - * of the file to write to - * @param Buffer The buffer to write from - * @param Count The number of bytes to write - * @return The number of bytes written, or - * errno on failure - * - * @note No permissions are required to - * call this syscall - */ - sys_FileWrite, - - /** - * This syscall is used to change the current - * offset in a file. - * - * @param FileDescriptor The file descriptor - * of the file to seek in - * @param Offset The offset to seek to - * @param Whence The seek mode - * (see FileSeekMode) - * @return The new offset, or errno on failure - * - * @note No permissions are required to - * call this syscall - */ - sys_FileSeek, - - /** - * This syscall is used to retrieve information - * about a file such as its size, permissions, - * etc. - * - * @param FileDescriptor The file descriptor - * of the file to get information about - * @param StatBuffer The buffer to store the - * information in - * @return 0 on success, errno on failure - * - * @note No permissions are required to - * call this syscall - */ - sys_FileStatus, - - /** - * - * Process syscalls - * - */ - - /** - * Creates/Reads/Writes/Deletes an IPC Pipe/Shared Memory/Message Queue/etc. - * - * @fn int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size) - * This syscall is used to create, read, write or delete an IPC Pipe/Shared Memory/Message Queue/etc. - */ - sys_IPC, - - /** - * Get/Set the local thread state - * - * @fn int LocalThreadStorage(int Code, unsigned long Address) - * This syscall is used to get or set the local thread state. - */ - sys_LocalThreadState, - - /** - * Sleep for a specific amount of time - * - * @fn int Sleep(uint64_t Milliseconds) - * This syscall is used to sleep the current thread for a specific amount of time. - */ - sys_Sleep, - - /** - * Fork the current process - * - * @fn int Fork() - * This syscall is used to create a new process that is a copy of the current process. - */ - sys_Fork, - - /** - * Wait for a process or a thread - * - * @fn - * This syscall is used to wait for a specific process or thread to terminate. It returns the exit code of the process or thread. - */ - sys_Wait, - - /** - * Kill a process or a thread - * - * @fn - * This syscall is used to send a termination signal to a specific process or thread - */ - sys_Kill, - - /** - * Spawn a new process - * - * @fn - * This syscall is used to create a new process with the provided path and arguments. - */ - sys_Spawn, - - /** - * Spawn a new thread - * - * @fn int SpawnThread(uint64_t InstructionPointer) - * This syscall is used to create a new thread within the current process with the provided function and arguments. - */ - sys_SpawnThread, - - /** - * Get thread list of a process - * - * @fn - * This syscall is used to retrieve a list of all the threads within a specific process. - */ - sys_GetThreadListOfProcess, - - /** - * Get current process - * - * @fn - * This syscall is used to retrieve information about the current process. - */ - sys_GetCurrentProcess, - - /** - * Get current thread - * - * @fn - * This syscall is used to retrieve information about the current thread. - */ - sys_GetCurrentThread, - - /** - * Get current process ID - * - * @fn int GetCurrentProcessID() - * This syscall is used to retrieve information about the current process. - */ - sys_GetCurrentProcessID, - - /** - * Get current thread ID - * - * @fn int GetCurrentThreadID() - * This syscall is used to retrieve information about the current thread. - */ - sys_GetCurrentThreadID, - - /** - * Get process by PID - * - * @fn - * This syscall is used to retrieve information about a specific process by its PID. - */ - sys_GetProcessByPID, - - /** - * Get thread by TID - * - * @fn - * This syscall is used to retrieve information about a specific thread by its TID. - */ - sys_GetThreadByTID, - - /** - * Kill a process - * - * @fn - * This syscall is used to send a termination signal to a specific process. - */ - sys_KillProcess, - - /** - * Kill a thread - * - * @fn - * This syscall is used to send a termination signal to a specific thread. - */ - sys_KillThread, - - /** - * Reserved syscall */ - - sys_SysReservedCreateProcess, - - /** - * Reserved syscall */ - - sys_SysReservedCreateThread, + sc_fork, /** Not a real syscall */ - sys_MaxSyscall + sc_MaxSyscall } NativeSyscalls; #ifndef syscall0 diff --git a/SystemCalls/Linux/Linux.cpp b/syscalls/linux.cpp similarity index 72% rename from SystemCalls/Linux/Linux.cpp rename to syscalls/linux.cpp index 27b37840..803bd816 100644 --- a/SystemCalls/Linux/Linux.cpp +++ b/syscalls/linux.cpp @@ -1,27 +1,26 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include #include #include -#include -#include "../../kernel.h" +#include "../kernel.h" #include "linux_syscalls.hpp" struct SyscallData @@ -32,8 +31,8 @@ struct SyscallData using InterProcessCommunication::IPC; using InterProcessCommunication::IPCID; -using Tasking::TaskStatus::Ready; -using Tasking::TaskStatus::Terminated; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; #define ARCH_SET_GS 0x1001 #define ARCH_SET_FS 0x1002 @@ -88,6 +87,41 @@ using Tasking::TaskStatus::Terminated; #define MAP_SYNC 0x80000 #define MAP_FIXED_NOREPLACE 0x100000 +#define linux_SIGHUP 1 +#define linux_SIGINT 2 +#define linux_SIGQUIT 3 +#define linux_SIGILL 4 +#define linux_SIGTRAP 5 +#define linux_SIGABRT 6 +#define linux_SIGIOT linux_SIGABRT +#define linux_SIGBUS 7 +#define linux_SIGFPE 8 +#define linux_SIGKILL 9 +#define linux_SIGUSR1 10 +#define linux_SIGSEGV 11 +#define linux_SIGUSR2 12 +#define linux_SIGPIPE 13 +#define linux_SIGALRM 14 +#define linux_SIGTERM 15 +#define linux_SIGSTKFLT 16 +#define linux_SIGCHLD 17 +#define linux_SIGCONT 18 +#define linux_SIGSTOP 19 +#define linux_SIGTSTP 20 +#define linux_SIGTTIN 21 +#define linux_SIGTTOU 22 +#define linux_SIGURG 23 +#define linux_SIGXCPU 24 +#define linux_SIGXFSZ 25 +#define linux_SIGVTALRM 26 +#define linux_SIGPROF 27 +#define linux_SIGWINCH 28 +#define linux_SIGIO 29 +#define linux_SIGPOLL 29 +#define linux_SIGPWR 30 +#define linux_SIGSYS 31 +#define linux_SIGUNUSED linux_SIGSYS + typedef int pid_t; struct iovec @@ -96,97 +130,79 @@ struct iovec size_t iov_len; }; -#if defined(a64) || defined(aa64) -static ssize_t ConvertErrno(ssize_t r) -{ - if (r >= 0) - return r; - return -errno; -} -#endif +typedef long __kernel_old_time_t; +typedef long __kernel_suseconds_t; -static int ConvertErrno(int r) +struct timeval { - if (r >= 0) - return r; - return -errno; -} + __kernel_old_time_t tv_sec; + __kernel_suseconds_t tv_usec; +}; + +struct rusage +{ + struct timeval ru_utime; + struct timeval ru_stime; + long ru_maxrss; + long ru_ixrss; + long ru_idrss; + long ru_isrss; + long ru_minflt; + long ru_majflt; + long ru_nswap; + long ru_inblock; + long ru_oublock; + long ru_msgsnd; + long ru_msgrcv; + long ru_nsignals; + long ru_nvcsw; + long ru_nivcsw; +}; + +/* From native functions */ +#define SysFrm SyscallsFrame +SysFrm *thisFrame; +ssize_t sys_read(SysFrm *, int, void *, size_t); +ssize_t sys_write(SysFrm *, int, const void *, size_t); +int sys_open(SysFrm *, const char *, int, mode_t); +int sys_close(SysFrm *, int); +off_t sys_lseek(SysFrm *, int, off_t, int); +void *sys_mmap(SysFrm *, void *, size_t, int, int, int, off_t); +int sys_mprotect(SysFrm *, void *, size_t, int); +int sys_munmap(SysFrm *, void *, size_t); +int sys_fork(SysFrm *); +int sys_execve(SysFrm *, const char *, char *const[], char *const[]); +__noreturn void sys_exit(SysFrm *, int); /* https://man7.org/linux/man-pages/man2/read.2.html */ -static ssize_t sys_read(int fd, void *buf, size_t count) +static ssize_t linux_read(int fd, void *buf, size_t count) { - debug("Reading %d bytes from fd %d", count, fd); - Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); - - if (!vmm.Check(buf, Memory::US)) - { - warn("Invalid address %#lx", buf); - return -EFAULT; - } - auto pBuf = pcb->PageTable->Get(buf); - - ssize_t ret = ConvertErrno(fdt->_read(fd, pBuf, count)); - debug("Read %d bytes from fd %d, got %d", count, fd, ret); - return ret; + return sys_read(thisFrame, fd, buf, count); } /* https://man7.org/linux/man-pages/man2/write.2.html */ -static ssize_t sys_write(int fd, const void *buf, size_t count) +static ssize_t linux_write(int fd, const void *buf, size_t count) { - debug("Writing %d bytes to fd %d", count, fd); - Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); - - if (!vmm.Check((void *)buf, Memory::US)) - { - warn("Invalid address %#lx", buf); - return -EFAULT; - } - auto pBuf = pcb->PageTable->Get(buf); - - ssize_t ret = ConvertErrno(fdt->_write(fd, pBuf, count)); - debug("Wrote %d bytes to fd %d, got %d", count, fd, ret); - return ret; + return sys_write(thisFrame, fd, buf, count); } /* https://man7.org/linux/man-pages/man2/open.2.html */ -static int sys_open(const char *pathname, int flags, mode_t mode) +static int linux_open(const char *pathname, int flags, mode_t mode) { - Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); - - if (!vmm.Check((void *)pathname, Memory::US)) - { - warn("Invalid address %#lx", pathname); - return -EFAULT; - } - auto pPathname = pcb->PageTable->Get(pathname); - - int ret = ConvertErrno(fdt->_open(pPathname, flags, mode)); - debug("Opened %s with flags %d and mode %d, got fd %d", - pPathname, flags, mode, ret); - return ret; + return sys_open(thisFrame, pathname, flags, mode); } /* https://man7.org/linux/man-pages/man2/close.2.html */ -static int sys_close(int fd) +static int linux_close(int fd) { - Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - int ret = ConvertErrno(fdt->_close(fd)); - debug("Closed fd %d, got %d", fd, ret); - return ret; + return sys_close(thisFrame, fd); } -/* https://man7.org/linux/man-pages/man3/stat.3p.html */ -static int sys_stat(const char *pathname, struct stat *statbuf) +/* https://man7.org/linux/man-pages/man2/stat.2.html */ +static int linux_stat(const char *pathname, struct stat *statbuf) { Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); if (!vmm.Check((void *)pathname, Memory::US)) @@ -196,15 +212,15 @@ static int sys_stat(const char *pathname, struct stat *statbuf) } auto pPathname = pcb->PageTable->Get(pathname); - return ConvertErrno(fdt->_stat(pPathname, statbuf)); + return fdt->_stat(pPathname, statbuf); } -/* https://man7.org/linux/man-pages/man3/fstat.3p.html */ -static int sys_fstat(int fd, struct stat *statbuf) +/* https://man7.org/linux/man-pages/man2/fstat.2.html */ +static int linux_fstat(int fd, struct stat *statbuf) { #undef fstat Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); if (!vmm.Check((void *)statbuf, Memory::US)) @@ -214,15 +230,15 @@ static int sys_fstat(int fd, struct stat *statbuf) } auto pStatbuf = pcb->PageTable->Get(statbuf); - return ConvertErrno(fdt->_fstat(fd, pStatbuf)); + return fdt->_fstat(fd, pStatbuf); } /* https://man7.org/linux/man-pages/man2/lstat.2.html */ -static int sys_lstat(const char *pathname, struct stat *statbuf) +static int linux_lstat(const char *pathname, struct stat *statbuf) { #undef lstat Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); if (!vmm.Check((void *)pathname, Memory::US)) @@ -240,139 +256,88 @@ static int sys_lstat(const char *pathname, struct stat *statbuf) auto pPathname = pcb->PageTable->Get(pathname); auto pStatbuf = pcb->PageTable->Get(statbuf); - return ConvertErrno(fdt->_lstat(pPathname, pStatbuf)); + return fdt->_lstat(pPathname, pStatbuf); } +#include "../syscalls.h" /* https://man7.org/linux/man-pages/man2/lseek.2.html */ -static off_t sys_lseek(int fd, off_t offset, int whence) +static off_t linux_lseek(int fd, off_t offset, int whence) { - Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; + int new_whence = 0; + if (whence == SEEK_SET) + new_whence = sc_SEEK_SET; + else if (whence == SEEK_CUR) + new_whence = sc_SEEK_CUR; + else if (whence == SEEK_END) + new_whence = sc_SEEK_END; - off_t ret = ConvertErrno(fdt->_lseek(fd, offset, whence)); - debug("(%d, %d, %d) = %d", fd, offset, whence, ret); - return ret; + return sys_lseek(thisFrame, fd, offset, new_whence); } -/* https://man7.org/linux/man-pages/man3/mmap.3p.html */ -static void *sys_mmap(void *addr, size_t length, int prot, - int flags, int fildes, off_t offset) +/* https://man7.org/linux/man-pages/man2/mmap.2.html */ +static void *linux_mmap(void *addr, size_t length, int prot, + int flags, int fildes, off_t offset) { - UNUSED(offset); /* FIXME */ - Tasking::PCB *pcb = thisProcess; - Memory::MemMgr *mm = pcb->Memory; + static_assert(PROT_NONE == sc_PROT_NONE); + static_assert(PROT_READ == sc_PROT_READ); + static_assert(PROT_WRITE == sc_PROT_WRITE); + static_assert(PROT_EXEC == sc_PROT_EXEC); - void *newPages = mm->RequestPages(TO_PAGES(length)); - if (newPages == nullptr) - return (void *)-ENOMEM; - - bool MustUseAddr = (flags & MAP_FIXED) != 0; - if (addr == NULL && !MustUseAddr) - addr = newPages; - - if (MustUseAddr) + int new_flags = 0; + if (flags & MAP_SHARED) { - debug("Using fixed address %#lx", addr); + new_flags |= sc_MAP_SHARED; + flags &= ~MAP_SHARED; } - - Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); - - uint64_t MapFlags = Memory::P; - if (prot & PROT_READ) - MapFlags |= Memory::US; - if (prot & PROT_WRITE) - MapFlags |= Memory::RW; - if (prot & PROT_EXEC) + if (flags & MAP_PRIVATE) { - debug("PROT_EXEC ignored"); /* MapFlags |= Memory::XD; */ + new_flags |= sc_MAP_PRIVATE; + flags &= ~MAP_PRIVATE; } - - switch (flags & MAP_TYPE) + if (flags & MAP_FIXED) { - case MAP_FILE: - debug("MAP_FILE ignored"); - [[fallthrough]]; - case MAP_SHARED: - fixme("MAP_SHARED not implemented"); - [[fallthrough]]; - case MAP_SHARED_VALIDATE: - fixme("MAP_SHARED_VALIDATE not implemented"); - [[fallthrough]]; - case MAP_PRIVATE: - debug("MAP_PRIVATE ignored"); - [[fallthrough]]; - case MAP_ANONYMOUS: - fixme("MAP_ANONYMOUS not implemented"); - [[fallthrough]]; - default: + new_flags |= sc_MAP_FIXED; + flags &= ~MAP_FIXED; + } + if (flags & MAP_ANONYMOUS) { - debug("mmap flags %#x", flags); - break; - } + new_flags |= sc_MAP_ANONYMOUS; + flags &= ~MAP_ANONYMOUS; } + if (flags) + fixme("unhandled flags: %#x", flags); - vmm.Map(addr, newPages, length, MapFlags, Memory::Virtual::FourKiB); - debug("Mapped %#lx to %#lx (%d pages)", addr, newPages, TO_PAGES(length)); + return sys_mmap(thisFrame, addr, length, prot, + new_flags, fildes, offset); +} +#undef __FENNIX_KERNEL_SYSCALLS_LIST_H__ - if (fildes != -1) - { - fixme("File mapping not implemented"); - mm->FreePages(newPages, TO_PAGES(length)); - return (void *)-ENOSYS; - } - - return addr; +/* https://man7.org/linux/man-pages/man2/mprotect.2.html */ +static int linux_mprotect(void *addr, size_t len, int prot) +{ + return sys_mprotect(thisFrame, addr, len, prot); } -/* https://man7.org/linux/man-pages/man3/mprotect.3p.html */ -static int sys_mprotect(void *addr, size_t len, int prot) +/* https://man7.org/linux/man-pages/man2/munmap.2.html */ +static int linux_munmap(void *addr, size_t length) { - Tasking::PCB *pcb = thisProcess; - - Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); - vmm.Map(addr, addr, len, Memory::P, Memory::Virtual::FourKiB); - - if (prot & PROT_READ) - vmm.Map(addr, addr, len, Memory::P | Memory::US, Memory::Virtual::FourKiB); - if (prot & PROT_WRITE) - vmm.Map(addr, addr, len, Memory::RW, Memory::Virtual::FourKiB); - if (prot & PROT_EXEC) - { - debug("PROT_EXEC ignored"); /* MapFlags |= Memory::XD; */ - } - - return 0; -} - -/* https://man7.org/linux/man-pages/man3/munmap.3p.html */ -static int sys_munmap(void *addr, size_t length) -{ - Tasking::PCB *pcb = thisProcess; - Memory::MemMgr *mm = pcb->Memory; - Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); - - mm->FreePages(addr, TO_PAGES(length)); - vmm.Unmap(addr, length, Memory::Virtual::FourKiB); - - return 0; + return sys_munmap(thisFrame, addr, length); } /* https://man7.org/linux/man-pages/man2/brk.2.html */ -static void *sys_brk(void *addr) +static void *linux_brk(void *addr) { - trace("Ignoring brk syscall..."); - return (void *)-ENOSYS; - // Tasking::PCB *pcb = thisProcess; - // void *ret = pcb->ProgramBreak->brk(addr); - // debug("brk(%#lx) = %#lx", addr, ret); - // return ret; + Tasking::PCB *pcb = thisProcess; + void *ret = pcb->ProgramBreak->brk(addr); + debug("brk(%#lx) = %#lx", addr, ret); + return ret; } /* https://man7.org/linux/man-pages/man2/ioctl.2.html */ -static int sys_ioctl(int fd, unsigned long request, void *argp) +static int linux_ioctl(int fd, unsigned long request, void *argp) { Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); if (!vmm.Check((void *)argp, Memory::US)) @@ -382,17 +347,26 @@ static int sys_ioctl(int fd, unsigned long request, void *argp) } auto pArgp = pcb->PageTable->Get(argp); - return ConvertErrno(fdt->_ioctl(fd, request, pArgp)); + return fdt->_ioctl(fd, request, pArgp); } -/* https://man7.org/linux/man-pages/man3/readv.3p.html */ -static ssize_t sys_readv(int fildes, const struct iovec *iov, int iovcnt) +/* https://man7.org/linux/man-pages/man2/readv.2.html */ +static ssize_t linux_readv(int fildes, const struct iovec *iov, int iovcnt) { + size_t iovec_size = sizeof(struct iovec) * iovcnt; + Tasking::PCB *pcb = thisProcess; + Memory::SmartHeap sh(iovec_size, pcb->vma); + { + Memory::SwapPT swap(pcb->PageTable); + memcpy(sh, iov, iovec_size); + } + iov = (struct iovec *)sh.Get(); + ssize_t Total = 0; for (int i = 0; i < iovcnt; i++) { debug("%d: iov[%d]: %p %d", fildes, i, iov[i].iov_base, iov[i].iov_len); - ssize_t n = sys_read(fildes, iov[i].iov_base, iov[i].iov_len); + ssize_t n = linux_read(fildes, iov[i].iov_base, iov[i].iov_len); if (n < 0) return n; debug("n: %d", n); @@ -408,14 +382,23 @@ static ssize_t sys_readv(int fildes, const struct iovec *iov, int iovcnt) return Total; } -/* https://man7.org/linux/man-pages/man3/writev.3p.html */ -static ssize_t sys_writev(int fildes, const struct iovec *iov, int iovcnt) +/* https://man7.org/linux/man-pages/man2/writev.2.html */ +static ssize_t linux_writev(int fildes, const struct iovec *iov, int iovcnt) { + size_t iovec_size = sizeof(struct iovec) * iovcnt; + Tasking::PCB *pcb = thisProcess; + Memory::SmartHeap sh(iovec_size, pcb->vma); + { + Memory::SwapPT swap(pcb->PageTable); + memcpy(sh, iov, iovec_size); + } + iov = (struct iovec *)sh.Get(); + ssize_t Total = 0; for (int i = 0; i < iovcnt; i++) { debug("%d: iov[%d]: %p %d", fildes, i, iov[i].iov_base, iov[i].iov_len); - ssize_t n = sys_write(fildes, iov[i].iov_base, iov[i].iov_len); + ssize_t n = linux_write(fildes, iov[i].iov_base, iov[i].iov_len); if (n < 0) return n; debug("n: %d", n); @@ -432,45 +415,116 @@ static ssize_t sys_writev(int fildes, const struct iovec *iov, int iovcnt) } /* https://man7.org/linux/man-pages/man2/dup.2.html */ -static int sys_dup(int oldfd) +static int linux_dup(int oldfd) { Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_dup(oldfd)); + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + return fdt->_dup(oldfd); } /* https://man7.org/linux/man-pages/man2/dup.2.html */ -static int sys_dup2(int oldfd, int newfd) +static int linux_dup2(int oldfd, int newfd) { Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_dup2(oldfd, newfd)); + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + return fdt->_dup2(oldfd, newfd); } -/* https://man7.org/linux/man-pages/man3/exit.3.html */ -static __noreturn void sys_exit(int status) +/* https://man7.org/linux/man-pages/man2/fork.2.html */ +static pid_t linux_fork() { - trace("Userspace thread %s(%d) exited with code %d (%#x)", - thisThread->Name, - thisThread->ID, status, - status < 0 ? -status : status); - - thisThread->ExitCode = status; - thisThread->Status = Terminated; - TaskManager->Yield(); - __builtin_unreachable(); + return sys_fork(thisFrame); } -/* https://man7.org/linux/man-pages/man3/creat.3p.html */ -static int sys_creat(const char *pathname, mode_t mode) +/* https://man7.org/linux/man-pages/man2/execve.2.html */ +static int linux_execve(const char *pathname, char *const argv[], + char *const envp[]) +{ + return sys_execve(thisFrame, pathname, argv, envp); +} + +/* https://man7.org/linux/man-pages/man2/exit.2.html */ +static __noreturn void linux_exit(int status) +{ + sys_exit(thisFrame, status); +} + +/* https://man7.org/linux/man-pages/man2/wait4.2.html */ +static pid_t linux_wait4(pid_t pid, int *wstatus, int options, struct rusage *rusage) +{ + static_assert(sizeof(struct rusage) < PAGE_SIZE); + + Tasking::PCB *pcb = thisProcess; + Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); + + if (!vmm.Check(rusage, Memory::US) && rusage != nullptr) + { + warn("Invalid address %#lx", rusage); + return -EFAULT; + } + + if (pid == -1) + pid = pcb->ID + 1; /* TODO: Wait for any child process */ + + Tasking::PCB *tPcb = pcb->GetContext()->GetProcessByID(pid); + + if (!tPcb) + { + warn("Invalid PID %d", pid); + return -ECHILD; + } + + tPcb->KeepInMemory = true; + + Tasking::TaskState state = tPcb->State; + debug("Waiting for %d(%#lx) state %d", pid, tPcb, state); + while (tPcb->State == state) + pcb->GetContext()->Yield(); + debug("Waited for %d(%#lx) state %d", pid, tPcb, state); + + if (wstatus) + { + int status = tPcb->ExitCode.load(); + + Memory::SwapPT swap(pcb->PageTable); + *wstatus = status; + } + + if (rusage != nullptr) + { + size_t kTime = tPcb->Info.KernelTime; + size_t uTime = tPcb->Info.UserTime; + size_t _maxrss = tPcb->GetSize(); + + { + Memory::SwapPT swap(pcb->PageTable); + + rusage->ru_utime.tv_sec = uTime / 1000000000000000; /* Seconds */ + rusage->ru_utime.tv_usec = uTime / 1000000000; /* Microseconds */ + + rusage->ru_stime.tv_sec = kTime / 1000000000000000; /* Seconds */ + rusage->ru_stime.tv_usec = kTime / 1000000000; /* Microseconds */ + + rusage->ru_maxrss = _maxrss; + /* TODO: The rest of the fields */ + } + } + + tPcb->KeepInMemory = false; + debug("%d", pid); + return pid; +} + +/* https://man7.org/linux/man-pages/man2/creat.2.html */ +static int linux_creat(const char *pathname, mode_t mode) { Tasking::PCB *pcb = thisProcess; - VirtualFileSystem::FileDescriptorTable *fdt = pcb->FileDescriptors; - return ConvertErrno(fdt->_creat(pathname, mode)); + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + return fdt->_creat(pathname, mode); } /* https://man7.org/linux/man-pages/man2/arch_prctl.2.html */ -static int sys_arch_prctl(int code, unsigned long addr) +static int linux_arch_prctl(int code, unsigned long addr) { Tasking::PCB *pcb = thisProcess; Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); @@ -557,8 +611,14 @@ static int sys_arch_prctl(int code, unsigned long addr) } } +/* https://man7.org/linux/man-pages/man2/gettid.2.html */ +static pid_t linux_gettid() +{ + return thisThread->ID; +} + /* https://man7.org/linux/man-pages/man2/set_tid_address.2.html */ -static pid_t sys_set_tid_address(int *tidptr) +static pid_t linux_set_tid_address(int *tidptr) { if (tidptr == nullptr) return -EINVAL; @@ -570,34 +630,34 @@ static pid_t sys_set_tid_address(int *tidptr) } /* https://man7.org/linux/man-pages/man2/exit_group.2.html */ -static __noreturn void sys_exit_group(int status) +static __noreturn void linux_exit_group(int status) { fixme("status=%d", status); - sys_exit(status); + linux_exit(status); } static SyscallData LinuxSyscallsTable[] = { - [__NR_read] = {"read", (void *)sys_read}, - [__NR_write] = {"write", (void *)sys_write}, - [__NR_open] = {"open", (void *)sys_open}, - [__NR_close] = {"close", (void *)sys_close}, - [__NR_stat] = {"stat", (void *)sys_stat}, - [__NR_fstat] = {"fstat", (void *)sys_fstat}, - [__NR_lstat] = {"lstat", (void *)sys_lstat}, + [__NR_read] = {"read", (void *)linux_read}, + [__NR_write] = {"write", (void *)linux_write}, + [__NR_open] = {"open", (void *)linux_open}, + [__NR_close] = {"close", (void *)linux_close}, + [__NR_stat] = {"stat", (void *)linux_stat}, + [__NR_fstat] = {"fstat", (void *)linux_fstat}, + [__NR_lstat] = {"lstat", (void *)linux_lstat}, [__NR_poll] = {"poll", (void *)nullptr}, - [__NR_lseek] = {"lseek", (void *)sys_lseek}, - [__NR_mmap] = {"mmap", (void *)sys_mmap}, - [__NR_mprotect] = {"mprotect", (void *)sys_mprotect}, - [__NR_munmap] = {"munmap", (void *)sys_munmap}, - [__NR_brk] = {"brk", (void *)sys_brk}, + [__NR_lseek] = {"lseek", (void *)linux_lseek}, + [__NR_mmap] = {"mmap", (void *)linux_mmap}, + [__NR_mprotect] = {"mprotect", (void *)linux_mprotect}, + [__NR_munmap] = {"munmap", (void *)linux_munmap}, + [__NR_brk] = {"brk", (void *)linux_brk}, [__NR_rt_sigaction] = {"rt_sigaction", (void *)nullptr}, [__NR_rt_sigprocmask] = {"rt_sigprocmask", (void *)nullptr}, [__NR_rt_sigreturn] = {"rt_sigreturn", (void *)nullptr}, - [__NR_ioctl] = {"ioctl", (void *)sys_ioctl}, + [__NR_ioctl] = {"ioctl", (void *)linux_ioctl}, [__NR_pread64] = {"pread64", (void *)nullptr}, [__NR_pwrite64] = {"pwrite64", (void *)nullptr}, - [__NR_readv] = {"readv", (void *)sys_readv}, - [__NR_writev] = {"writev", (void *)sys_writev}, + [__NR_readv] = {"readv", (void *)linux_readv}, + [__NR_writev] = {"writev", (void *)linux_writev}, [__NR_access] = {"access", (void *)nullptr}, [__NR_pipe] = {"pipe", (void *)nullptr}, [__NR_select] = {"select", (void *)nullptr}, @@ -609,8 +669,8 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_shmget] = {"shmget", (void *)nullptr}, [__NR_shmat] = {"shmat", (void *)nullptr}, [__NR_shmctl] = {"shmctl", (void *)nullptr}, - [__NR_dup] = {"dup", (void *)sys_dup}, - [__NR_dup2] = {"dup2", (void *)sys_dup2}, + [__NR_dup] = {"dup", (void *)linux_dup}, + [__NR_dup2] = {"dup2", (void *)linux_dup2}, [__NR_pause] = {"pause", (void *)nullptr}, [__NR_nanosleep] = {"nanosleep", (void *)nullptr}, [__NR_getitimer] = {"getitimer", (void *)nullptr}, @@ -634,11 +694,11 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_setsockopt] = {"setsockopt", (void *)nullptr}, [__NR_getsockopt] = {"getsockopt", (void *)nullptr}, [__NR_clone] = {"clone", (void *)nullptr}, - [__NR_fork] = {"fork", (void *)nullptr}, + [__NR_fork] = {"fork", (void *)linux_fork}, [__NR_vfork] = {"vfork", (void *)nullptr}, - [__NR_execve] = {"execve", (void *)nullptr}, - [__NR_exit] = {"exit", (void *)sys_exit}, - [__NR_wait4] = {"wait4", (void *)nullptr}, + [__NR_execve] = {"execve", (void *)linux_execve}, + [__NR_exit] = {"exit", (void *)linux_exit}, + [__NR_wait4] = {"wait4", (void *)linux_wait4}, [__NR_kill] = {"kill", (void *)nullptr}, [__NR_uname] = {"uname", (void *)nullptr}, [__NR_semget] = {"semget", (void *)nullptr}, @@ -662,7 +722,7 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_rename] = {"rename", (void *)nullptr}, [__NR_mkdir] = {"mkdir", (void *)nullptr}, [__NR_rmdir] = {"rmdir", (void *)nullptr}, - [__NR_creat] = {"creat", (void *)sys_creat}, + [__NR_creat] = {"creat", (void *)linux_creat}, [__NR_link] = {"link", (void *)nullptr}, [__NR_unlink] = {"unlink", (void *)nullptr}, [__NR_symlink] = {"symlink", (void *)nullptr}, @@ -735,7 +795,7 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_pivot_root] = {"pivot_root", (void *)nullptr}, [__NR__sysctl] = {"_sysctl", (void *)nullptr}, [__NR_prctl] = {"prctl", (void *)nullptr}, - [__NR_arch_prctl] = {"arch_prctl", (void *)sys_arch_prctl}, + [__NR_arch_prctl] = {"arch_prctl", (void *)linux_arch_prctl}, [__NR_adjtimex] = {"adjtimex", (void *)nullptr}, [__NR_setrlimit] = {"setrlimit", (void *)nullptr}, [__NR_chroot] = {"chroot", (void *)nullptr}, @@ -763,7 +823,7 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_afs_syscall] = {"afs_syscall", (void *)nullptr}, [__NR_tuxcall] = {"tuxcall", (void *)nullptr}, [__NR_security] = {"security", (void *)nullptr}, - [__NR_gettid] = {"gettid", (void *)nullptr}, + [__NR_gettid] = {"gettid", (void *)linux_gettid}, [__NR_readahead] = {"readahead", (void *)nullptr}, [__NR_setxattr] = {"setxattr", (void *)nullptr}, [__NR_lsetxattr] = {"lsetxattr", (void *)nullptr}, @@ -795,7 +855,7 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_epoll_wait_old] = {"epoll_wait_old", (void *)nullptr}, [__NR_remap_file_pages] = {"remap_file_pages", (void *)nullptr}, [__NR_getdents64] = {"getdents64", (void *)nullptr}, - [__NR_set_tid_address] = {"set_tid_address", (void *)sys_set_tid_address}, + [__NR_set_tid_address] = {"set_tid_address", (void *)linux_set_tid_address}, [__NR_restart_syscall] = {"restart_syscall", (void *)nullptr}, [__NR_semtimedop] = {"semtimedop", (void *)nullptr}, [__NR_fadvise64] = {"fadvise64", (void *)nullptr}, @@ -808,7 +868,7 @@ static SyscallData LinuxSyscallsTable[] = { [__NR_clock_gettime] = {"clock_gettime", (void *)nullptr}, [__NR_clock_getres] = {"clock_getres", (void *)nullptr}, [__NR_clock_nanosleep] = {"clock_nanosleep", (void *)nullptr}, - [__NR_exit_group] = {"exit_group", (void *)sys_exit_group}, + [__NR_exit_group] = {"exit_group", (void *)linux_exit_group}, [__NR_epoll_wait] = {"epoll_wait", (void *)nullptr}, [__NR_epoll_ctl] = {"epoll_ctl", (void *)nullptr}, [__NR_tgkill] = {"tgkill", (void *)nullptr}, @@ -1028,6 +1088,7 @@ static SyscallData LinuxSyscallsTable[] = { uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame) { + thisFrame = Frame; #if defined(a64) if (Frame->rax > sizeof(LinuxSyscallsTable) / sizeof(SyscallData)) { @@ -1048,13 +1109,16 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame) return -ENOSYS; } - debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )", + debug("> [%d:\"%s\"]( %#lx %#lx %#lx %#lx %#lx %#lx )", Frame->rax, Syscall.Name, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9); - return call(Frame->rdi, Frame->rsi, Frame->rdx, - Frame->r10, Frame->r8, Frame->r9); + long sc_ret = call(Frame->rdi, Frame->rsi, Frame->rdx, + Frame->r10, Frame->r8, Frame->r9); + + debug("< [%d:\"%s\"] = %d", Frame->rax, Syscall.Name, sc_ret); + return sc_ret; #elif defined(a32) if (Frame->eax > sizeof(LinuxSyscallsTable) / sizeof(SyscallData)) { @@ -1075,14 +1139,17 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame) return -ENOSYS; } - debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )", + debug("> [%d:\"%s\"]( %#lx %#lx %#lx %#lx %#lx %#lx )", Frame->eax, Syscall.Name, Frame->ebx, Frame->ecx, Frame->edx, Frame->esi, Frame->edi, Frame->ebp); - return call(Frame->ebx, Frame->ecx, Frame->edx, - Frame->esi, Frame->edi, Frame->ebp); + int sc_ret = call(Frame->ebx, Frame->ecx, Frame->edx, + Frame->esi, Frame->edi, Frame->ebp); + + debug("< [%d:\"%s\"] = %d", Frame->eax, Syscall.Name, sc_ret); + return sc_ret; #elif defined(aa64) - return 0; + return -ENOSYS; #endif } diff --git a/syscalls/linux/.gitkeep b/syscalls/linux/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/SystemCalls/Linux/linux_syscalls.hpp b/syscalls/linux_syscalls.hpp similarity index 93% rename from SystemCalls/Linux/linux_syscalls.hpp rename to syscalls/linux_syscalls.hpp index 7d81d7d9..ab6620f3 100644 --- a/SystemCalls/Linux/linux_syscalls.hpp +++ b/syscalls/linux_syscalls.hpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_LINUX_SYSCALLS_H__ diff --git a/syscalls/native.cpp b/syscalls/native.cpp new file mode 100644 index 00000000..340d5c1f --- /dev/null +++ b/syscalls/native.cpp @@ -0,0 +1,230 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../syscalls.h" +#include "../kernel.h" +#include "../ipc.h" + +struct SyscallData +{ + const char *Name; + void *Handler; + int RequiredID; +}; + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +void sys_exit(SysFrm *, int status); + +void *sys_mmap(SysFrm *, + void *addr, size_t len, + int prot, int flags, + int fildes, off_t off); + +int sys_munmap(SysFrm *, + void *addr, size_t len); + +int sys_mprotect(SysFrm *, + void *addr, size_t len, + int prot); + +int sys_open(SysFrm *, + const char *path, + int oflag, mode_t mode); + +int sys_close(SysFrm *, + int fildes); + +ssize_t sys_read(SysFrm *, int fildes, + void *buf, size_t nbyte); + +ssize_t sys_write(SysFrm *, int fildes, + const void *buf, + size_t nbyte); + +off_t sys_lseek(SysFrm *, int fildes, + off_t offset, int whence); + +int sys_fork(SysFrm *Frame); + +static SyscallData NativeSyscallsTable[sc_MaxSyscall] = { + [sc_exit] = { + "exit", + (void *)sys_exit, + UINT16_MAX, + }, + [sc_mmap] = { + "mmap", + (void *)sys_mmap, + UINT16_MAX, + }, + [sc_munmap] = { + "munmap", + (void *)sys_munmap, + UINT16_MAX, + }, + [sc_mprotect] = { + "mprotect", + (void *)sys_mprotect, + UINT16_MAX, + }, + [sc_open] = { + "open", + (void *)sys_open, + UINT16_MAX, + }, + [sc_close] = { + "close", + (void *)sys_close, + UINT16_MAX, + }, + [sc_read] = { + "read", + (void *)sys_read, + UINT16_MAX, + }, + [sc_write] = { + "write", + (void *)sys_write, + UINT16_MAX, + }, + [sc_lseek] = { + "lseek", + (void *)sys_lseek, + UINT16_MAX, + }, + [sc_fork] = { + "fork", + (void *)sys_fork, + UINT16_MAX, + }, +}; + +uintptr_t HandleNativeSyscalls(SysFrm *Frame) +{ +#if defined(a64) + if (unlikely(Frame->rax > sc_MaxSyscall)) + { + fixme("Syscall %ld not implemented.", Frame->rax); + return -ENOSYS; + } + + SyscallData Syscall = NativeSyscallsTable[Frame->rax]; + + uintptr_t (*call)(SysFrm *, uintptr_t, ...) = + r_cst(uintptr_t(*)(SysFrm *, uintptr_t, ...), + Syscall.Handler); + + if (unlikely(!call)) + { + error("Syscall %s(%d) not implemented.", + Syscall.Name, Frame->rax); + return -ENOSYS; + } + + int euid = thisProcess->Security.Effective.UserID; + int egid = thisProcess->Security.Effective.GroupID; + int reqID = Syscall.RequiredID; + if (euid > reqID || egid > reqID) + { + warn("Process %s(%d) tried to access a system call \"%s\" with insufficient privileges.", + thisProcess->Name, thisProcess->ID, Syscall.Name); + debug("Required: %d; Effective u:%d, g:%d", reqID, euid, egid); + return -EPERM; + } + + debug("> [%d:\"%s\"]( %#lx %#lx %#lx %#lx %#lx %#lx )", + Frame->rax, Syscall.Name, + Frame->rdi, Frame->rsi, Frame->rdx, + Frame->r10, Frame->r8, Frame->r9); + + long sc_ret = call(Frame, + Frame->rdi, Frame->rsi, Frame->rdx, + Frame->r10, Frame->r8, Frame->r9); + + debug("< [%d:\"%s\"] = %d", + Frame->rax, Syscall.Name, sc_ret); + return sc_ret; +#elif defined(a32) + if (unlikely(Frame->eax > sc_MaxSyscall)) + { + fixme("Syscall %ld not implemented.", Frame->eax); + return -ENOSYS; + } + + SyscallData Syscall = NativeSyscallsTable[Frame->eax]; + + uintptr_t (*call)(SysFrm *, uintptr_t, ...) = + r_cst(uintptr_t(*)(SysFrm *, uintptr_t, ...), + Syscall.Handler); + + if (unlikely(!call)) + { + error("Syscall %s(%d) not implemented.", + Syscall.Name, Frame->eax); + return -ENOSYS; + } + + int euid = thisProcess->Security.Effective.UserID; + int egid = thisProcess->Security.Effective.GroupID; + int reqID = Syscall.RequiredID; + if (euid > reqID || egid > reqID) + { + warn("Process %s(%d) tried to access a system call \"%s\" with insufficient privileges.", + thisProcess->Name, thisProcess->ID, Syscall.Name); + debug("Required: %d; Effective u:%d, g:%d", reqID, euid, egid); + return -EPERM; + } + + debug("> [%d:\"%s\"]( %#x %#x %#x %#x %#x %#x )", + Frame->eax, Syscall.Name, + Frame->ebx, Frame->ecx, Frame->edx, + Frame->esi, Frame->edi, Frame->ebp); + + int sc_ret = call(Frame, + Frame->ebx, Frame->ecx, Frame->edx, + Frame->esi, Frame->edi, Frame->ebp); + + debug("< [%d:\"%s\"] = %d", + Frame->eax, Syscall.Name, sc_ret); + return sc_ret; +#elif defined(aa64) + return -ENOSYS; +#endif +} diff --git a/syscalls/native/close.cpp b/syscalls/native/close.cpp new file mode 100644 index 00000000..8410625e --- /dev/null +++ b/syscalls/native/close.cpp @@ -0,0 +1,54 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/close.html */ +int sys_close(SysFrm *, + int fildes) +{ + function("%d", fildes); + PCB *pcb = thisProcess; + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + return fdt->_close(fildes); +} diff --git a/syscalls/native/execve.cpp b/syscalls/native/execve.cpp new file mode 100644 index 00000000..a1e0ac3c --- /dev/null +++ b/syscalls/native/execve.cpp @@ -0,0 +1,213 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using vfs::RefNode; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html */ +int sys_execve(SysFrm *Frame, const char *path, + char *const argv[], char *const envp[]) +{ + PCB *pcb = thisProcess; + Memory::Virtual vmm(pcb->PageTable); + + if (path == nullptr || + !vmm.Check((void *)path, Memory::US) || + !vmm.Check((void *)argv, Memory::US) || + !vmm.Check((void *)envp, Memory::US)) + return -ENOENT; + + const char *safe_path; + char **safe_argv; + char **safe_envp; + safe_path = (const char *)pcb->vma->RequestPages(1); + safe_argv = (char **)pcb->vma->RequestPages(TO_PAGES(MAX_ARG)); + safe_envp = (char **)pcb->vma->RequestPages(TO_PAGES(MAX_ARG)); + { + Memory::SwapPT swap(pcb->PageTable); + size_t len = strlen(path); + memset((void *)safe_path, 0, PAGE_SIZE); + memcpy((void *)safe_path, path, len); + + const char *arg; + char *n_arg; + for (int i = 0; argv[i] != nullptr; i++) + { + arg = argv[i]; + size_t len = strlen(arg); + + n_arg = (char *)pcb->vma->RequestPages(TO_PAGES(len)); + memcpy((void *)n_arg, arg, len); + n_arg[len] = '\0'; + + safe_argv[i] = n_arg; + + if (likely(i < MAX_ARG - 1)) + safe_argv[i + 1] = nullptr; + } + + for (int i = 0; envp[i] != nullptr; i++) + { + arg = envp[i]; + size_t len = strlen(arg); + + n_arg = (char *)pcb->vma->RequestPages(TO_PAGES(len)); + memcpy((void *)n_arg, arg, len); + n_arg[len] = '\0'; + + safe_envp[i] = n_arg; + + if (likely(i < MAX_ARG - 1)) + safe_envp[i + 1] = nullptr; + } + } + + function("%s %#lx %#lx", safe_path, safe_argv, safe_envp); + +#ifdef DEBUG + for (int i = 0; safe_argv[i] != nullptr; i++) + debug("safe_argv[%d]: %s", i, safe_argv[i]); + + for (int i = 0; safe_envp[i] != nullptr; i++) + debug("safe_envp[%d]: %s", i, safe_envp[i]); +#endif + + RefNode *File = fs->Open(safe_path, + pcb->CurrentWorkingDirectory); + + if (!File) + { + error("File not found"); + return -ENOENT; + } + + char shebang_magic[2]; + File->read((uint8_t *)shebang_magic, 2); + + if (shebang_magic[0] == '#' && shebang_magic[1] == '!') + { + char *orig_path = (char *)pcb->vma->RequestPages(TO_PAGES(strlen(path) + 1)); + memcpy(orig_path, path, strlen(path) + 1); + + char *shebang = (char *)safe_path; + size_t shebang_len = 0; + constexpr int shebang_len_max = 255; + File->seek(2, SEEK_SET); + off_t shebang_off = 2; + while (true) + { + char c; + if (File->node->read((uint8_t *)&c, 1, shebang_off) == 0) + break; + if (c == '\n' || shebang_len == shebang_len_max) + break; + shebang[shebang_len++] = c; + shebang_off++; + } + shebang[shebang_len] = '\0'; + debug("Shebang: %s", shebang); + + char **c_safe_argv = (char **)pcb->vma->RequestPages(TO_PAGES(MAX_ARG)); + int i = 0; + for (; safe_argv[i] != nullptr; i++) + { + size_t arg_len = strlen(safe_argv[i]); + char *c_arg = (char *)pcb->vma->RequestPages(TO_PAGES(arg_len)); + memcpy((void *)c_arg, safe_argv[i], arg_len); + c_arg[arg_len] = '\0'; + + c_safe_argv[i] = c_arg; + debug("c_safe_argv[%d]: %s", i, c_safe_argv[i]); + } + c_safe_argv[i] = nullptr; + + char *token = strtok(shebang, " "); + i = 0; + while (token != nullptr) + { + size_t len = strlen(token); + char *t_arg = (char *)pcb->vma->RequestPages(TO_PAGES(len)); + memcpy((void *)t_arg, token, len); + t_arg[len] = '\0'; + + safe_argv[i++] = t_arg; + token = strtok(nullptr, " "); + } + + safe_argv[i++] = orig_path; + for (int j = 1; c_safe_argv[j] != nullptr; j++) + { + safe_argv[i++] = c_safe_argv[j]; + debug("clone: safe_argv[%d]: %s", + i, safe_argv[i - 1]); + } + safe_argv[i] = nullptr; + + delete File; + return sys_execve(Frame, safe_argv[0], + (char *const *)safe_argv, + (char *const *)safe_envp); + } + + int ret = Execute::Spawn((char *)safe_path, + (const char **)safe_argv, + (const char **)safe_envp, + pcb->Parent, pcb->Info.Compatibility); + + if (ret < 0) + { + error("Failed to spawn"); + delete File; + return ret; + } + + delete File; + Tasking::Task *ctx = pcb->GetContext(); + ctx->Sleep(1000); + pcb->State = Tasking::Zombie; + pcb->ExitCode = 0; + while (true) + ctx->Yield(); + __builtin_unreachable(); +} diff --git a/syscalls/native/exit.cpp b/syscalls/native/exit.cpp new file mode 100644 index 00000000..116a95a9 --- /dev/null +++ b/syscalls/native/exit.cpp @@ -0,0 +1,62 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/exit.html */ +__noreturn void sys_exit(SysFrm *, int status) +{ + TCB *t = thisThread; + + trace("Userspace thread %s(%d) exited with code %d (%#x)", + t->Name, + t->ID, status, + status < 0 ? -status : status); + + t->ExitCode = status; + t->KeepTime = TimeManager->CalculateTarget(10, Time::Seconds); + t->State = Terminated; + while (true) + t->GetContext()->Yield(); + __builtin_unreachable(); +} diff --git a/syscalls/native/fork.cpp b/syscalls/native/fork.cpp new file mode 100644 index 00000000..555409bb --- /dev/null +++ b/syscalls/native/fork.cpp @@ -0,0 +1,141 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/fork.html */ +int sys_fork(SysFrm *Frame) +{ + assert(Frame != nullptr); + +#ifdef a32 + return -ENOSYS; +#endif + PCB *Parent = thisThread->Parent; + TCB *Thread = thisThread; + + void *ProcSymTable = nullptr; + if (Parent->ELFSymbolTable) + ProcSymTable = Parent->ELFSymbolTable->GetImage(); + + PCB *NewProcess = + TaskManager->CreateProcess(Parent, + Parent->Name, + Parent->Security.ExecutionMode, + ProcSymTable); + + if (!NewProcess) + { + error("Failed to create process for fork"); + return -EAGAIN; + } + + NewProcess->IPC->Fork(Parent->IPC); + + TCB *NewThread = + TaskManager->CreateThread(NewProcess, + 0, + nullptr, + nullptr, + std::vector(), + Thread->Info.Architecture, + Thread->Info.Compatibility, + true); + + NewThread->Rename(Thread->Name); + + if (!NewThread) + { + error("Failed to create thread for fork"); + return -EAGAIN; + } + + TaskManager->UpdateFrame(); + + /* This if statement will overwrite + most of the registers except rcx + and r8-r15 */ + if (thisThread->ID == NewThread->ID) + { + /* We can't just return 0; because the + gsTCB->SyscallStack is no + longer valid */ +#if defined(a64) + asmv("movq $0, %rax\n"); /* Return 0 */ + asmv("movq %r8, %rsp\n"); /* Restore stack pointer */ + asmv("movq %r8, %rbp\n"); /* Restore base pointer */ + asmv("swapgs\n"); /* Swap GS back to the user GS */ + asmv("sti\n"); /* Enable interrupts */ + asmv("sysretq\n"); /* Return to rcx address in user mode */ +#elif defined(a32) +#warning "sys_fork not implemented for i386" +#endif + __builtin_unreachable(); + } + + memcpy(&NewThread->FPU, &Thread->FPU, sizeof(CPU::x64::FXState)); + NewThread->Stack->Fork(Thread->Stack); + NewThread->Info.Architecture = Thread->Info.Architecture; + NewThread->Info.Compatibility = Thread->Info.Compatibility; + NewThread->Registers = Thread->Registers; +#if defined(a64) + /* For sysretq */ + NewThread->Registers.rcx = Frame->ReturnAddress; + NewThread->Registers.r8 = Frame->StackPointer; +#endif + + if (Thread->Security.IsCritical) + NewThread->SetCritical(true); + +#ifdef a86 + NewThread->GSBase = NewThread->ShadowGSBase; + NewThread->ShadowGSBase = Thread->ShadowGSBase; + NewThread->FSBase = Thread->FSBase; +#endif + + debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", + Thread->Name, Thread->ID, + NewThread->Name, NewThread->ID); + NewThread->State = Ready; + return (int)NewProcess->ID; +} diff --git a/syscalls/native/lseek.cpp b/syscalls/native/lseek.cpp new file mode 100644 index 00000000..9f046251 --- /dev/null +++ b/syscalls/native/lseek.cpp @@ -0,0 +1,54 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/lseek.html */ +off_t sys_lseek(SysFrm *, int fildes, + off_t offset, int whence) +{ + function("%d, %d, %d", fildes, offset, whence); + PCB *pcb = thisProcess; + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + return fdt->_lseek(fildes, offset, whence); +} diff --git a/syscalls/native/mmap.cpp b/syscalls/native/mmap.cpp new file mode 100644 index 00000000..7ca6dfac --- /dev/null +++ b/syscalls/native/mmap.cpp @@ -0,0 +1,113 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/mmap.html */ +void *sys_mmap(SysFrm *, + void *addr, size_t len, + int prot, int flags, + int fildes, off_t off) +{ + if (len == 0) + return (void *)-EINVAL; + + if (fildes != -1) + return (void *)-ENOSYS; + + bool p_None = prot & sc_PROT_NONE; + bool p_Read = prot & sc_PROT_READ; + bool p_Write = prot & sc_PROT_WRITE; + bool p_Exec = prot & sc_PROT_EXEC; + + bool m_Shared = flags & sc_MAP_SHARED; + bool m_Private = flags & sc_MAP_PRIVATE; + bool m_Fixed = flags & sc_MAP_FIXED; + bool m_Anon = flags & sc_MAP_ANONYMOUS; + + UNUSED(p_None); + UNUSED(m_Anon); + + debug("N:%d R:%d W:%d E:%d", + p_None, p_Read, p_Write, + p_Exec); + + debug("S:%d P:%d F:%d A:%d", + m_Shared, m_Private, + m_Fixed, m_Anon); + + int UnknownFlags = flags & ~(sc_MAP_SHARED | + sc_MAP_PRIVATE | + sc_MAP_FIXED | + sc_MAP_ANONYMOUS); + + if (UnknownFlags) + { + debug("Unknown flags: %x", UnknownFlags); + return (void *)-EINVAL; + } + + if (len > PAGE_SIZE_2M) + fixme("large page 2 MiB (requested %d)", + TO_MiB(len)); + else if (len > PAGE_SIZE_1G) + fixme("huge page 1 GiB (requested %d)", + TO_GiB(len)); + + if (off % PAGE_SIZE) + return (void *)-EINVAL; + + if (uintptr_t(addr) % PAGE_SIZE && m_Fixed) + return (void *)-EINVAL; + + if ((m_Shared && m_Private) || + (!m_Shared && !m_Private)) + return (void *)-EINVAL; + + Tasking::PCB *pcb = thisProcess; + Memory::VirtualMemoryArea *vma = pcb->vma; + intptr_t ret = (intptr_t)vma->CreateCoWRegion(addr, len, + p_Read, p_Write, p_Exec, + m_Fixed, m_Shared); + + return (void *)ret; +} diff --git a/syscalls/native/mprotect.cpp b/syscalls/native/mprotect.cpp new file mode 100644 index 00000000..fb42d970 --- /dev/null +++ b/syscalls/native/mprotect.cpp @@ -0,0 +1,107 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/mprotect.html */ +int sys_mprotect(SysFrm *, + void *addr, size_t len, int prot) +{ + if (len == 0) + return -EINVAL; + + if (uintptr_t(addr) % PAGE_SIZE) + return -EINVAL; + + bool p_None = prot & sc_PROT_NONE; + bool p_Read = prot & sc_PROT_READ; + bool p_Write = prot & sc_PROT_WRITE; + // bool p_Exec = prot & sc_PROT_EXEC; + + Tasking::PCB *pcb = thisProcess; + Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); + + for (uintptr_t i = uintptr_t(addr); + i < uintptr_t(addr) + len; + i += PAGE_SIZE) + { + if (likely(!vmm.Check((void *)i, Memory::G))) + { + Memory::PageTableEntry *pte = vmm.GetPTE(addr); + if (!pte->Present || + (!pte->UserSupervisor && p_Read) || + (!pte->ReadWrite && p_Write)) + { + debug("Page %p is not mapped with the correct permissions", + (void *)i); + return -EACCES; + } + + pte->Present = p_None; + pte->UserSupervisor = p_Read; + pte->ReadWrite = p_Write; + // pte->ExecuteDisable = p_Exec; + +#if defined(a64) + CPU::x64::invlpg(addr); +#elif defined(a32) + CPU::x32::invlpg(addr); +#elif defined(aa64) + asmv("dsb sy"); + asmv("tlbi vae1is, %0" + : + : "r"(addr) + : "memory"); + asmv("dsb sy"); + asmv("isb"); +#endif + } + else + { + warn("%p is a global page", (void *)i); + return -ENOMEM; + } + } + + return 0; +} diff --git a/syscalls/native/munmap.cpp b/syscalls/native/munmap.cpp new file mode 100644 index 00000000..f5ab1d38 --- /dev/null +++ b/syscalls/native/munmap.cpp @@ -0,0 +1,74 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/munmap.html */ +int sys_munmap(SysFrm *, + void *addr, size_t len) +{ + if (uintptr_t(addr) % PAGE_SIZE) + return -EINVAL; + + if (len == 0) + return -EINVAL; + + Tasking::PCB *pcb = thisProcess; + Memory::VirtualMemoryArea *vma = pcb->vma; + Memory::Virtual vmm = Memory::Virtual(pcb->PageTable); + + for (uintptr_t i = uintptr_t(addr); + i < uintptr_t(addr) + len; + i += PAGE_SIZE) + { + if (likely(!vmm.Check((void *)i, Memory::G))) + vmm.Remap((void *)i, (void *)i, Memory::P | Memory::RW); + else + warn("%p is a global page", (void *)i); + } + + /* TODO: Check if the page is allocated + and not only mapped */ + vma->FreePages((void *)addr, TO_PAGES(len) + 1); + return 0; +} diff --git a/syscalls/native/open.cpp b/syscalls/native/open.cpp new file mode 100644 index 00000000..99d67f74 --- /dev/null +++ b/syscalls/native/open.cpp @@ -0,0 +1,64 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/open.html */ +int sys_open(SysFrm *, + const char *path, + int oflag, mode_t mode) +{ + const char *safe_path = nullptr; + Tasking::PCB *pcb = thisProcess; + Memory::SmartHeap sh(512, pcb->vma); + safe_path = (const char *)sh.Get(); + { + Memory::SwapPT swap(pcb->PageTable); + size_t len = strlen(path); + memcpy((void *)safe_path, path, len); + } + + function("%s, %d, %d", safe_path, oflag, mode); + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + return fdt->_open(safe_path, oflag, mode); +} diff --git a/syscalls/native/read.cpp b/syscalls/native/read.cpp new file mode 100644 index 00000000..109ef28e --- /dev/null +++ b/syscalls/native/read.cpp @@ -0,0 +1,68 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/read.html */ +ssize_t sys_read(SysFrm *, int fildes, + void *buf, size_t nbyte) +{ + void *safe_buf = nullptr; + Tasking::PCB *pcb = thisProcess; + Memory::SmartHeap sh(nbyte, pcb->vma); + safe_buf = sh.Get(); + + function("%d, %p, %d", fildes, buf, nbyte); + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + ssize_t ret = fdt->_read(fildes, safe_buf, nbyte); + if (ret >= 0) + fdt->_lseek(fildes, ret, SEEK_CUR); + else + return ret; + + { + Memory::SwapPT swap(pcb->PageTable); + memcpy(buf, safe_buf, nbyte); + } + return ret; +} diff --git a/syscalls/native/write.cpp b/syscalls/native/write.cpp new file mode 100644 index 00000000..7c446aa0 --- /dev/null +++ b/syscalls/native/write.cpp @@ -0,0 +1,65 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include +#include +#include +#include + +#include "../../syscalls.h" +#include "../../kernel.h" +#include "../../ipc.h" + +using InterProcessCommunication::IPC; +using InterProcessCommunication::IPCID; +using Tasking::PCB; +using Tasking::TCB; +using Tasking::TaskState::Ready; +using Tasking::TaskState::Terminated; +using namespace Memory; + +#define SysFrm SyscallsFrame + +#if defined(a64) +typedef long arch_t; +#elif defined(a32) +typedef int arch_t; +#endif + +/* https://pubs.opengroup.org/onlinepubs/009604499/functions/write.html */ +ssize_t sys_write(SysFrm *, int fildes, + const void *buf, size_t nbyte) +{ + const void *safe_buf = nullptr; + Tasking::PCB *pcb = thisProcess; + Memory::SmartHeap sh(nbyte, pcb->vma); + safe_buf = sh.Get(); + { + Memory::SwapPT swap(pcb->PageTable); + memcpy((void *)safe_buf, buf, nbyte); + } + + function("%d, %p, %d", fildes, buf, nbyte); + vfs::FileDescriptorTable *fdt = pcb->FileDescriptors; + ssize_t ret = fdt->_write(fildes, safe_buf, nbyte); + if (ret) + fdt->_lseek(fildes, ret, SEEK_CUR); + return ret; +} diff --git a/syscalls/syscalls.cpp b/syscalls/syscalls.cpp new file mode 100644 index 00000000..d077a576 --- /dev/null +++ b/syscalls/syscalls.cpp @@ -0,0 +1,99 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include + +#include "../kernel.h" + +class AutoSwitchPageTable +{ +private: + uintptr_t Original; + +public: + AutoSwitchPageTable() + { +#if defined(a86) + asmv("mov %%cr3, %0" + : "=r"(Original)); + + asmv("mov %0, %%cr3" + : + : "r"(KernelPageTable)); +#endif + } + + ~AutoSwitchPageTable() + { +#if defined(a86) + asmv("mov %0, %%cr3" + : + : "r"(Original)); +#endif + } +}; + +extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame) +{ + /* Automatically switch to kernel page table + and switch back when this function returns. */ + AutoSwitchPageTable PageSwitcher; + + uint64_t _ctime = TimeManager->GetCounter(); + Tasking::TaskInfo *Ptinfo = &thisProcess->Info; + Tasking::TaskInfo *Ttinfo = &thisThread->Info; + uintptr_t ret; + + if (Config.UseLinuxSyscalls) + { + ret = HandleLinuxSyscalls(Frame); + goto Ret; + } + + switch (Ttinfo->Compatibility) + { + case Tasking::TaskCompatibility::Native: + { + ret = HandleNativeSyscalls(Frame); + break; + } + case Tasking::TaskCompatibility::Linux: + { + ret = HandleLinuxSyscalls(Frame); + break; + } + case Tasking::TaskCompatibility::Windows: + { + error("Windows compatibility not implemented yet."); + assert(false); + break; + } + default: + { + error("Unknown compatibility mode!"); + assert(false); + break; + } + } + +Ret: + Ptinfo->KernelTime += TimeManager->GetCounter() - _ctime; + Ttinfo->KernelTime += TimeManager->GetCounter() - _ctime; + return ret; +} diff --git a/Tasking/InterProcessCommunication.cpp b/tasking/ipc.cpp similarity index 81% rename from Tasking/InterProcessCommunication.cpp rename to tasking/ipc.cpp index e1d97846..f00cd66d 100644 --- a/Tasking/InterProcessCommunication.cpp +++ b/tasking/ipc.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -31,9 +31,9 @@ namespace InterProcessCommunication foreach (auto Hnd in ParentHandles) { debug("Forking IPC with ID %d", Hnd->ID); - IPCHandle *NewHnd = (IPCHandle *)mem->RequestPages(TO_PAGES(sizeof(IPCHandle) + 1)); + IPCHandle *NewHnd = (IPCHandle *)vma->RequestPages(TO_PAGES(sizeof(IPCHandle) + 1)); memcpy(NewHnd, Hnd, sizeof(IPCHandle)); - NewHnd->Node = vfs->Create(Hnd->Node->Name, VirtualFileSystem::NodeFlags::FILE, IPCNode); + NewHnd->Node = fs->Create(Hnd->Node->Name, vfs::NodeType::FILE, IPCNode); Handles.push_back(NewHnd); } } @@ -42,10 +42,10 @@ namespace InterProcessCommunication { UNUSED(Type); SmartLock(this->IPCLock); - IPCHandle *Hnd = (IPCHandle *)mem->RequestPages(TO_PAGES(sizeof(IPCHandle) + 1)); + IPCHandle *Hnd = (IPCHandle *)vma->RequestPages(TO_PAGES(sizeof(IPCHandle) + 1)); Hnd->ID = NextID++; - Hnd->Node = vfs->Create(UniqueToken, VirtualFileSystem::NodeFlags::FILE, IPCNode); + Hnd->Node = fs->Create(UniqueToken, vfs::NodeType::FILE, IPCNode); Hnd->Buffer = nullptr; Hnd->Length = 0; Hnd->Listening = false; @@ -62,8 +62,8 @@ namespace InterProcessCommunication { if ((*itr)->ID == ID) { - vfs->Delete((*itr)->Node); - mem->FreePages((*itr), TO_PAGES(sizeof(IPCHandle) + 1)); + fs->Delete((*itr)->Node); + vma->FreePages((*itr), TO_PAGES(sizeof(IPCHandle) + 1)); Handles.erase(itr); debug("Destroyed IPC with ID %d", ID); return IPCSuccess; @@ -87,7 +87,7 @@ namespace InterProcessCommunication if (Hnd->Buffer != nullptr || Hnd->Length != 0) return IPCAlreadyAllocated; - Hnd->Buffer = (uint8_t *)mem->RequestPages(TO_PAGES(Size + 1)); + Hnd->Buffer = (uint8_t *)vma->RequestPages(TO_PAGES(Size + 1)); Hnd->Length = Size; return IPCSuccess; } @@ -105,7 +105,7 @@ namespace InterProcessCommunication if (Hnd->Buffer == nullptr || Hnd->Length == 0) return IPCNotAllocated; - mem->FreePages(Hnd->Buffer, TO_PAGES(Hnd->Length + 1)); + vma->FreePages(Hnd->Buffer, TO_PAGES(Hnd->Length + 1)); Hnd->Buffer = nullptr; Hnd->Length = 0; return IPCSuccess; @@ -262,14 +262,16 @@ namespace InterProcessCommunication IPC::IPC(void *Process) { + Tasking::PCB *pcb = (Tasking::PCB *)Process; this->Process = Process; - mem = new Memory::MemMgr(nullptr, ((Tasking::PCB *)Process)->memDirectory); - IPCNode = vfs->Create("ipc", VirtualFileSystem::NodeFlags::DIRECTORY, ((Tasking::PCB *)this->Process)->ProcessDirectory); + this->vma = new Memory::VirtualMemoryArea(pcb->PageTable); + IPCNode = fs->Create("ipc", vfs::NodeType::DIRECTORY, + pcb->ProcessDirectory); } IPC::~IPC() { - delete mem, mem = nullptr; - vfs->Delete(IPCNode, true); + fs->Delete(IPCNode, true); + delete this->vma, this->vma = nullptr; } } diff --git a/Tasking/Process.cpp b/tasking/process.cpp similarity index 65% rename from Tasking/Process.cpp rename to tasking/process.cpp index 870b7ec8..da0b5138 100644 --- a/Tasking/Process.cpp +++ b/tasking/process.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -27,10 +27,10 @@ #include "../kernel.h" #if defined(a64) -#include "../Architecture/amd64/cpu/apic.hpp" -#include "../Architecture/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/apic.hpp" +#include "../arch/amd64/cpu/gdt.hpp" #elif defined(a32) -#include "../Architecture/i386/cpu/apic.hpp" +#include "../arch/i386/cpu/apic.hpp" #elif defined(aa64) #endif @@ -45,8 +45,8 @@ #endif using namespace InterProcessCommunication; -using namespace VirtualFileSystem; -using VirtualFileSystem::NodeFlags; +using namespace vfs; +using vfs::NodeType; namespace Tasking { @@ -59,24 +59,44 @@ namespace Tasking this->Name, name); if (this->Name) + { + this->AllocatedMemory -= strlen(this->Name) + 1; delete[] this->Name; + } this->Name = new char[strlen(name) + 1]; + this->AllocatedMemory += strlen(name) + 1; strcpy((char *)this->Name, name); } - void PCB::SetWorkingDirectory(VirtualFileSystem::Node *node) + void PCB::SetWorkingDirectory(vfs::Node *node) { trace("Setting working directory of process %s to %#lx (%s)", this->Name, node, node->Name); CurrentWorkingDirectory = node; } + size_t PCB::GetSize() + { + size_t ret = this->AllocatedMemory; + ret += this->vma->GetAllocatedMemorySize(); + + for (size_t i = 0; i < this->Threads.size(); i++) + ret += sizeof(TCB); + + for (size_t i = 0; i < this->Children.size(); i++) + ret += sizeof(PCB); + + return ret; + } + PCB::PCB(Task *ctx, PCB *Parent, const char *Name, TaskExecutionMode ExecutionMode, void *Image, bool DoNotCreatePageTable, uint16_t UserID, uint16_t GroupID) { + debug("+ %#lx", this); + assert(ctx != nullptr); assert(Name != nullptr); assert(strlen(Name) > 0); @@ -136,9 +156,7 @@ namespace Tasking char ProcFSName[12]; sprintf(ProcFSName, "%d", this->ID); - this->ProcessDirectory = vfs->Create(ProcFSName, DIRECTORY, ProcFS); - this->memDirectory = vfs->Create("mem", DIRECTORY, this->ProcessDirectory); - + this->ProcessDirectory = fs->Create(ProcFSName, DIRECTORY, ProcFS); this->FileDescriptors = new FileDescriptorTable(this); /* If create page table */ @@ -154,60 +172,70 @@ namespace Tasking this->Name, this->ID, this->PageTable); } - this->Memory = new Memory::MemMgr(this->PageTable, this->memDirectory); - this->ProgramBreak = new Memory::ProgramBreak(this->PageTable, this->Memory); - + this->vma = new Memory::VirtualMemoryArea(this->PageTable); + this->ProgramBreak = new Memory::ProgramBreak(this->PageTable, this->vma); this->IPC = new class IPC((void *)this); if (Image) + { this->ELFSymbolTable = new SymbolResolver::Symbols((uintptr_t)Image); + this->AllocatedMemory += sizeof(SymbolResolver::Symbols); + } if (Parent) Parent->Children.push_back(this); debug("Process page table: %#lx", this->PageTable); - debug("Created process \"%s\"(%d). Parent \"%s\"(%d)", + debug("Created %s process \"%s\"(%d). Parent \"%s\"(%d)", + ExecutionMode == TaskExecutionMode::User ? "user" : "kernel", this->Name, this->ID, Parent ? this->Parent->Name : "None", Parent ? this->Parent->ID : 0); + this->AllocatedMemory += strlen(Name) + 1; + this->AllocatedMemory += sizeof(PCB); + this->AllocatedMemory += sizeof(FileDescriptorTable); + this->AllocatedMemory += FROM_PAGES(TO_PAGES(sizeof(Memory::PageTable) + 1)); + this->AllocatedMemory += sizeof(Memory::VirtualMemoryArea); + this->AllocatedMemory += sizeof(Memory::ProgramBreak); + this->AllocatedMemory += sizeof(class IPC); + this->Info.SpawnTime = TimeManager->GetCounter(); ctx->ProcessList.push_back(this); } PCB::~PCB() { + debug("- %#lx", this); debug("Destroying process \"%s\"(%d)", this->Name, this->ID); + debug("Removing from process list"); /* Remove us from the process list so we don't get scheduled anymore */ ctx->ProcessList.erase(std::find(ctx->ProcessList.begin(), ctx->ProcessList.end(), this)); - /* If we have a symbol table allocated, - we need to free it */ + debug("Freeing symbol table strings"); if (this->ELFSymbolTable) delete this->ELFSymbolTable; - /* Free IPC */ + debug("Freeing IPC"); delete this->IPC; - /* Free all allocated memory */ + debug("Freeing allocated memory"); delete this->ProgramBreak; - delete this->Memory; + delete this->vma; - /* Closing all open files */ + debug("Closing file descriptors"); delete this->FileDescriptors; - /* Free Name */ - delete[] this->Name; - /* If we own the pointer to the PageTable, we need to free it */ if (this->PageTable && OwnPageTable) { + debug("Freeing page table"); size_t PTPgs = TO_PAGES(sizeof(Memory::PageTable) + 1); KernelAllocator.FreePages(this->PageTable, PTPgs); } @@ -220,11 +248,13 @@ namespace Tasking foreach (auto tcb in this->Threads) delete tcb; - /* Delete /proc/{pid} directory */ - vfs->Delete(this->ProcessDirectory, true); + debug("Removing /proc/%d", this->ID); + fs->Delete(this->ProcessDirectory, true); - /* If we have a Parent, remove us from - their children list */ + /* Free Name */ + delete[] this->Name; + + debug("Removing from parent process"); if (this->Parent) { std::vector &pChild = this->Parent->Children; diff --git a/Tasking/Scheduler.cpp b/tasking/scheduler.cpp similarity index 84% rename from Tasking/Scheduler.cpp rename to tasking/scheduler.cpp index 48f87fa9..1a990a20 100644 --- a/Tasking/Scheduler.cpp +++ b/tasking/scheduler.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -27,11 +27,11 @@ #include "../kernel.h" #if defined(a64) -#include "../Architecture/amd64/cpu/apic.hpp" -#include "../Architecture/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/apic.hpp" +#include "../arch/amd64/cpu/gdt.hpp" #elif defined(a32) -#include "../Architecture/i386/cpu/apic.hpp" -#include "../Architecture/i386/cpu/gdt.hpp" +#include "../arch/i386/cpu/apic.hpp" +#include "../arch/i386/cpu/gdt.hpp" #elif defined(aa64) #endif @@ -130,19 +130,19 @@ namespace Tasking #endif foreach (auto process in ProcessList) { - if (InvalidPCB(process)) + if (unlikely(InvalidPCB(process))) continue; - switch (process->Status.load()) + switch (process->State.load()) { - case TaskStatus::Ready: + case TaskState::Ready: fnp_schedbg("Ready process (%s)%d", process->Name, process->ID); break; default: fnp_schedbg("Process \"%s\"(%d) status %d", process->Name, process->ID, - process->Status); + process->State); /* We don't actually remove the process. RemoveProcess firstly checks if it's terminated, if not, it will @@ -154,10 +154,10 @@ namespace Tasking foreach (auto thread in process->Threads) { - if (InvalidTCB(thread)) + if (unlikely(InvalidTCB(thread))) continue; - if (thread->Status.load() != TaskStatus::Ready) + if (thread->State.load() != TaskState::Ready) continue; if (thread->Info.Affinity[CurrentCPU->ID] == false) @@ -204,7 +204,7 @@ namespace Tasking CurrentCPU->CurrentProcess->Threads[i]->ID, nextThread->Name, nextThread->ID); - if (nextThread->Status.load() != TaskStatus::Ready) + if (nextThread->State.load() != TaskState::Ready) { gnat_schedbg("Thread %d is not ready", nextThread->ID); TempIndex++; @@ -251,13 +251,13 @@ namespace Tasking continue; } - if (InvalidPCB(process)) + if (unlikely(InvalidPCB(process))) { gnap_schedbg("Invalid process %#lx", process); continue; } - if (process->Status.load() != TaskStatus::Ready) + if (process->State.load() != TaskState::Ready) { gnap_schedbg("Process %d is not ready", process->ID); continue; @@ -265,13 +265,13 @@ namespace Tasking foreach (auto thread in process->Threads) { - if (InvalidTCB(thread)) + if (unlikely(InvalidTCB(thread))) { gnap_schedbg("Invalid thread %#lx", thread); continue; } - if (thread->Status.load() != TaskStatus::Ready) + if (thread->State.load() != TaskState::Ready) { gnap_schedbg("Thread %d is not ready", thread->ID); continue; @@ -297,13 +297,13 @@ namespace Tasking foreach (auto process in ProcessList) { - if (InvalidPCB(process)) + if (unlikely(InvalidPCB(process))) { sspt_schedbg("Invalid process %#lx", process); continue; } - if (process->Status.load() != TaskStatus::Ready) + if (process->State.load() != TaskState::Ready) { sspt_schedbg("Process %d is not ready", process->ID); continue; @@ -311,13 +311,13 @@ namespace Tasking foreach (auto thread in process->Threads) { - if (InvalidTCB(thread)) + if (unlikely(InvalidTCB(thread))) { sspt_schedbg("Invalid thread %#lx", thread); continue; } - if (thread->Status.load() != TaskStatus::Ready) + if (thread->State.load() != TaskState::Ready) { sspt_schedbg("Thread %d is not ready", thread->ID); continue; @@ -336,21 +336,26 @@ namespace Tasking return false; } - SafeFunction NIF void Task::UpdateProcessStatus() + SafeFunction NIF void Task::UpdateProcessState() { foreach (auto process in ProcessList) { - if (InvalidPCB(process)) + if (unlikely(InvalidPCB(process))) continue; - if (process->Status.load() == TaskStatus::Terminated || - process->Status.load() == TaskStatus::Zombie) + if (process->State.load() == TaskState::Terminated) continue; + if (process->Threads.size() == 1) + { + process->State.exchange(process->Threads[0]->State.load()); + continue; + } + bool AllThreadsSleeping = true; foreach (auto thread in process->Threads) { - if (thread->Status.load() != TaskStatus::Sleeping) + if (thread->State.load() != TaskState::Sleeping) { AllThreadsSleeping = false; break; @@ -358,9 +363,9 @@ namespace Tasking } if (AllThreadsSleeping) - process->Status.store(TaskStatus::Sleeping); - else if (process->Status.load() == TaskStatus::Sleeping) - process->Status.store(TaskStatus::Ready); + process->State.store(TaskState::Sleeping); + else if (process->State.load() == TaskState::Sleeping) + process->State.store(TaskState::Ready); } } @@ -368,27 +373,29 @@ namespace Tasking { foreach (auto process in ProcessList) { - if (InvalidPCB(process)) + if (unlikely(InvalidPCB(process))) continue; - if (process->Status.load() == TaskStatus::Terminated || - process->Status.load() == TaskStatus::Zombie) + Tasking::TaskState pState = process->State.load(); + if (pState != TaskState::Ready && + pState != TaskState::Sleeping && + pState != TaskState::Blocked) continue; foreach (auto thread in process->Threads) { - if (InvalidTCB(thread)) + if (unlikely(InvalidTCB(thread))) continue; - if (thread->Status.load() != TaskStatus::Sleeping) + if (likely(thread->State.load() != TaskState::Sleeping)) continue; /* Check if the thread is ready to wake up. */ - if (thread->Info.SleepUntil < TimeManager->GetCounter()) + if (unlikely(thread->Info.SleepUntil < TimeManager->GetCounter())) { - if (process->Status.load() == TaskStatus::Sleeping) - process->Status.store(TaskStatus::Ready); - thread->Status.store(TaskStatus::Ready); + if (pState == TaskState::Sleeping) + process->State.store(TaskState::Ready); + thread->State.store(TaskState::Ready); thread->Info.SleepUntil = 0; wut_schedbg("Thread \"%s\"(%d) woke up.", thread->Name, thread->ID); @@ -412,6 +419,9 @@ namespace Tasking "00AA00", /* Running */ "FFAA00", /* Sleeping */ "FFAA00", /* Blocked */ + "FFAA00", /* Stopped */ + "FFAA00", /* Waiting */ + "FF0088", /* Zombie */ "FF0000", /* Terminated */ }; @@ -421,8 +431,10 @@ namespace Tasking "Ready", "Run", "Sleep", + "Block", "Wait", - "Stop", + + "Zombie", "Terminated", }; @@ -452,15 +464,15 @@ namespace Tasking printf("\eF02C21Task Manager\n"); foreach (auto Proc in TaskManager->GetProcessList()) { - int Status = Proc->Status; + int State = Proc->State; printf("\e%s-> \eAABBCC%s \e00AAAA%s\n", - Statuses[Status], Proc->Name, StatusesSign[Status]); + Statuses[State], Proc->Name, StatusesSign[State]); foreach (auto Thd in Proc->Threads) { - Status = Thd->Status; + State = Thd->State; printf(" \e%s-> \eAABBCC%s \e00AAAA%s\n\eAABBCC", - Statuses[Status], Thd->Name, StatusesSign[Status]); + Statuses[State], Thd->Name, StatusesSign[State]); } } register uintptr_t CurrentStackAddress asm("rsp"); @@ -479,7 +491,7 @@ namespace Tasking SafeFunction NIF void Task::Schedule(CPU::x32::TrapFrame *Frame) #endif { - if (StopScheduler) + if (unlikely(StopScheduler)) { warn("Scheduler stopped."); return; @@ -500,7 +512,7 @@ namespace Tasking #ifdef DEBUG_SCHEDULER { schedbg("================================================================"); - schedbg("Status: 0-ukn | 1-rdy | 2-run | 3-wait | 4-term"); + schedbg("State: 0-ukn | 1-rdy | 2-run | 3-wait | 4-term"); schedbg("Technical Informations on regs %#lx", Frame->InterruptNumber); size_t ds; asmv("mov %%ds, %0" @@ -522,7 +534,8 @@ namespace Tasking } #endif - if (unlikely(InvalidPCB(CurrentCPU->CurrentProcess.load()) || InvalidTCB(CurrentCPU->CurrentThread.load()))) + if (unlikely(InvalidPCB(CurrentCPU->CurrentProcess.load()) || + InvalidTCB(CurrentCPU->CurrentThread.load()))) { schedbg("Invalid process or thread. Finding a new one."); ProcessNotChanged = true; @@ -545,19 +558,22 @@ namespace Tasking CurrentCPU->CurrentThread->FSBase = uintptr_t(CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE)); #endif - if (CurrentCPU->CurrentProcess->Status.load() == TaskStatus::Running) - CurrentCPU->CurrentProcess->Status.store(TaskStatus::Ready); - if (CurrentCPU->CurrentThread->Status.load() == TaskStatus::Running) - CurrentCPU->CurrentThread->Status.store(TaskStatus::Ready); + if (CurrentCPU->CurrentProcess->State.load() == TaskState::Running) + CurrentCPU->CurrentProcess->State.store(TaskState::Ready); + if (CurrentCPU->CurrentThread->State.load() == TaskState::Running) + CurrentCPU->CurrentThread->State.store(TaskState::Ready); - this->UpdateProcessStatus(); - schedbg("Passed UpdateProcessStatus"); + this->UpdateProcessState(); + schedbg("Passed UpdateProcessState"); this->WakeUpThreads(); schedbg("Passed WakeUpThreads"); if (this->SchedulerUpdateTrapFrame) + { + this->SchedulerUpdateTrapFrame = false; goto Success; + } if (this->GetNextAvailableThread(CurrentCPU)) { @@ -616,8 +632,8 @@ namespace Tasking CurrentCPU->CurrentThread->Security.ExecutionMode, CurrentCPU->ID); - CurrentCPU->CurrentProcess->Status.store(TaskStatus::Running); - CurrentCPU->CurrentThread->Status.store(TaskStatus::Running); + CurrentCPU->CurrentProcess->State.store(TaskState::Running); + CurrentCPU->CurrentThread->State.store(TaskState::Running); *Frame = CurrentCPU->CurrentThread->Registers; @@ -628,10 +644,6 @@ namespace Tasking CurrentCPU->CurrentThread->IPHistory[0] = Frame->rip; GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop())); - CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable}); - /* Not sure if this is needed, but it's better to be safe than sorry. */ - asmv("movq %cr3, %rax"); - asmv("movq %rax, %cr3"); CPU::x64::fxrstor(&CurrentCPU->CurrentThread->FPU); CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, CurrentCPU->CurrentThread->ShadowGSBase); CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase); @@ -640,10 +652,6 @@ namespace Tasking CurrentCPU->CurrentThread->IPHistory[0] = Frame->eip; GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop())); - CPU::x32::writecr3({.raw = (uint32_t)CurrentCPU->CurrentProcess->PageTable}); - /* Not sure if this is needed, but it's better to be safe than sorry. */ - asmv("movl %cr3, %eax"); - asmv("movl %eax, %cr3"); CPU::x32::fxrstor(&CurrentCPU->CurrentThread->FPU); CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, CurrentCPU->CurrentThread->ShadowGSBase); CPU::x32::wrmsr(CPU::x32::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase); @@ -714,6 +722,11 @@ namespace Tasking End: this->SchedulerTicks.store(size_t(TimeManager->GetCounter() - SchedTmpTicks)); +#ifdef a64 + CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable}); +#else + CPU::x32::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable}); +#endif } #ifdef a64 diff --git a/Tasking/Task.cpp b/tasking/task.cpp similarity index 71% rename from Tasking/Task.cpp rename to tasking/task.cpp index 84dadef2..434d2c0b 100644 --- a/Tasking/Task.cpp +++ b/tasking/task.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -27,10 +27,10 @@ #include "../kernel.h" #if defined(a64) -#include "../Architecture/amd64/cpu/apic.hpp" -#include "../Architecture/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/apic.hpp" +#include "../arch/amd64/cpu/gdt.hpp" #elif defined(a32) -#include "../Architecture/i386/cpu/apic.hpp" +#include "../arch/i386/cpu/apic.hpp" #elif defined(aa64) #endif @@ -67,11 +67,11 @@ namespace Tasking return true; /* Uninitialized pointers may have uintptr_t max value instead of nullptr. */ - if (pcb >= (PCB *)(UINTPTR_MAX - 0x1ffe)) + if (pcb >= (PCB *)(UINTPTR_MAX - 0x1FFE)) return true; /* In this section of the memory is reserved by the kernel. */ - if (pcb < (PCB *)(0x1000)) + if (pcb < (PCB *)(0xFFFFF)) return true; /* Check if it's mapped. */ @@ -87,11 +87,11 @@ namespace Tasking return true; /* Uninitialized pointers may have uintptr_t max value instead of nullptr. */ - if (tcb >= (TCB *)(UINTPTR_MAX - 0x1ffe)) + if (tcb >= (TCB *)(UINTPTR_MAX - 0x1FFE)) return true; /* In this section of the memory is reserved by the kernel. */ - if (tcb < (TCB *)(0x1000)) + if (tcb < (TCB *)(0xFFFFF)) return true; /* Check if it's mapped. */ @@ -101,37 +101,44 @@ namespace Tasking return false; } - SafeFunction void Task::RemoveThread(TCB *Thread) + SafeFunction bool Task::RemoveThread(TCB *Thread) { - foreach (TCB *tcb in Thread->Parent->Threads) - { - if (tcb == Thread) - { - debug("Thread \"%s\"(%d) removed from process \"%s\"(%d)", - Thread->Name, Thread->ID, Thread->Parent->Name, - Thread->Parent->ID); - delete tcb; - break; - } - } + if (Thread->KeepInMemory.load() == true) + return false; + if (Thread->KeepTime > TimeManager->GetCounter()) + return false; + + debug("Thread \"%s\"(%d) removed from process \"%s\"(%d)", + Thread->Name, Thread->ID, Thread->Parent->Name, + Thread->Parent->ID); + + delete Thread; + return true; } - SafeFunction void Task::RemoveProcess(PCB *Process) + SafeFunction bool Task::RemoveProcess(PCB *Process) { - if (InvalidPCB(Process)) - return; + if (unlikely(InvalidPCB(Process))) + return false; - if (Process->Status == Terminated) + if (Process->State == Terminated) { + if (Process->KeepInMemory.load() == true) + return false; + if (Process->KeepTime > TimeManager->GetCounter()) + return false; + delete Process; - return; + return true; } - foreach (TCB *thread in Process->Threads) + foreach (TCB *Thread in Process->Threads) { - if (thread->Status == Terminated) - RemoveThread(thread); + if (Thread->State == Terminated) + RemoveThread(Thread); } + + return true; } SafeFunction void Task::UpdateUsage(TaskInfo *Info, TaskExecutionMode Mode, int Core) @@ -161,8 +168,10 @@ namespace Tasking { SmartLock(TaskingLock); foreach (auto p in ProcessList) + { if (p->ID == ID) return p; + } return nullptr; } @@ -172,69 +181,73 @@ namespace Tasking foreach (auto p in ProcessList) { foreach (auto t in p->Threads) + { if (t->ID == ID) return t; + } } return nullptr; } void Task::WaitForProcess(PCB *pcb) { - if (InvalidPCB(pcb)) + if (unlikely(InvalidPCB(pcb))) return; - if (pcb->Status == TaskStatus::UnknownStatus) + if (pcb->State == TaskState::UnknownStatus) return; debug("Waiting for process \"%s\"(%d)", pcb->Name, pcb->ID); - while (pcb->Status != TaskStatus::Terminated) + while (pcb->State != TaskState::Terminated && + pcb->State != TaskState::Zombie) this->Yield(); } void Task::WaitForThread(TCB *tcb) { - if (InvalidTCB(tcb)) + if (unlikely(InvalidTCB(tcb))) return; - if (tcb->Status == TaskStatus::UnknownStatus) + if (tcb->State == TaskState::UnknownStatus) return; debug("Waiting for thread \"%s\"(%d)", tcb->Name, tcb->ID); - while (tcb->Status != TaskStatus::Terminated) + while (tcb->State != TaskState::Terminated && + tcb->State != TaskState::Zombie) this->Yield(); } - void Task::WaitForProcessStatus(PCB *pcb, TaskStatus status) + void Task::WaitForProcessStatus(PCB *pcb, TaskState status) { - if (InvalidPCB(pcb)) + if (unlikely(InvalidPCB(pcb))) return; - if (pcb->Status == TaskStatus::UnknownStatus) + if (pcb->State == TaskState::UnknownStatus) return; debug("Waiting for process \"%s\"(%d) to reach status: %d", pcb->Name, pcb->ID, status); - while (pcb->Status != status) + while (pcb->State != status) this->Yield(); } - void Task::WaitForThreadStatus(TCB *tcb, TaskStatus status) + void Task::WaitForThreadStatus(TCB *tcb, TaskState status) { - if (InvalidTCB(tcb)) + if (unlikely(InvalidTCB(tcb))) return; - if (tcb->Status == TaskStatus::UnknownStatus) + if (tcb->State == TaskState::UnknownStatus) return; debug("Waiting for thread \"%s\"(%d) to reach status: %d", tcb->Name, tcb->ID, status); - while (tcb->Status != status) + while (tcb->State != status) this->Yield(); } @@ -243,24 +256,24 @@ namespace Tasking TCB *thread = this->GetCurrentThread(); PCB *process = this->GetCurrentProcess(); - thread->Status = TaskStatus::Sleeping; + thread->State = TaskState::Sleeping; { SmartLock(TaskingLock); if (process->Threads.size() == 1) - process->Status = TaskStatus::Sleeping; + process->State = TaskState::Sleeping; thread->Info.SleepUntil = TimeManager->CalculateTarget(Milliseconds, Time::Units::Milliseconds); } -#ifdef DEBUG - uint64_t TicksNow = TimeManager->GetCounter(); -#endif - debug("Thread \"%s\"(%d) is going to sleep until %llu, current %llu, diff %llu", - thread->Name, thread->ID, thread->Info.SleepUntil, - TicksNow, thread->Info.SleepUntil - TicksNow); + // #ifdef DEBUG + // uint64_t TicksNow = TimeManager->GetCounter(); + // #endif + // debug("Thread \"%s\"(%d) is going to sleep until %llu, current %llu, diff %llu", + // thread->Name, thread->ID, thread->Info.SleepUntil, + // TicksNow, thread->Info.SleepUntil - TicksNow); if (!NoSwitch) this->Yield(); @@ -281,12 +294,12 @@ namespace Tasking this->Sleep(2000); { SmartLock(TaskingLock); - foreach (auto process in ProcessList) + foreach (auto Process in ProcessList) { - if (InvalidPCB(process)) + if (unlikely(InvalidPCB(Process))) continue; - RemoveProcess(process); + RemoveProcess(Process); } } } @@ -298,13 +311,13 @@ namespace Tasking const char **argv, const char **envp, const std::vector &auxv, - TaskArchitecture Architecture, + TaskArchitecture arch, TaskCompatibility Compatibility, bool ThreadNotReady) { SmartLock(TaskingLock); return new TCB(this, Parent, EntryPoint, - argv, envp, auxv, Architecture, + argv, envp, auxv, arch, Compatibility, ThreadNotReady); } @@ -343,7 +356,9 @@ namespace Tasking PCB *kproc = CreateProcess(nullptr, "Kernel", TaskExecutionMode::Kernel); kproc->ELFSymbolTable = KernelSymbolTable; - TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector(), Arch); + TCB *kthrd = CreateThread(kproc, EntryPoint, + nullptr, nullptr, + std::vector(), Arch); kthrd->Rename("Main Thread"); debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name); @@ -434,8 +449,8 @@ namespace Tasking foreach (PCB *Process in ProcessList) { debug("Process %s(%d) is still running (or waiting to be removed status %#lx)", - Process->Name, Process->ID, Process->Status); - if (Process->Status == TaskStatus::Terminated) + Process->Name, Process->ID, Process->State); + if (Process->State == TaskState::Terminated) continue; NotTerminated++; } diff --git a/Tasking/Thread.cpp b/tasking/thread.cpp similarity index 85% rename from Tasking/Thread.cpp rename to tasking/thread.cpp index 3653af85..1a52f00e 100644 --- a/Tasking/Thread.cpp +++ b/tasking/thread.cpp @@ -1,22 +1,23 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include +#include #include #include #include @@ -27,11 +28,11 @@ #include "../kernel.h" #if defined(a64) -#include "../Architecture/amd64/cpu/apic.hpp" -#include "../Architecture/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/apic.hpp" +#include "../arch/amd64/cpu/gdt.hpp" #elif defined(a32) -#include "../Architecture/i386/cpu/apic.hpp" -#include "../Architecture/i386/cpu/gdt.hpp" +#include "../arch/i386/cpu/apic.hpp" +#include "../arch/i386/cpu/gdt.hpp" #elif defined(aa64) #endif @@ -50,7 +51,7 @@ void ThreadDoExit() { CPUData *CPUData = GetCurrentCPU(); Tasking::TCB *CurrentThread = CPUData->CurrentThread.load(); - CurrentThread->Status = Tasking::TaskStatus::Terminated; + CurrentThread->State = Tasking::TaskState::Terminated; debug("\"%s\"(%d) exited with code: %#lx", CurrentThread->Name, @@ -70,9 +71,13 @@ namespace Tasking this->Name, name); if (this->Name) + { + this->AllocatedMemory -= strlen(this->Name) + 1; delete[] this->Name; + } this->Name = new char[strlen(name) + 1]; + this->AllocatedMemory += strlen(name) + 1; strcpy((char *)this->Name, name); } @@ -111,6 +116,14 @@ namespace Tasking Security.IsKernelDebugEnabled = Enable; } + size_t TCB::GetSize() + { + size_t ret = this->AllocatedMemory; + ret += this->vma->GetAllocatedMemorySize(); + ret += this->Stack->GetSize(); + return ret; + } + void TCB::SYSV_ABI_Call(uintptr_t Arg1, uintptr_t Arg2, uintptr_t Arg3, uintptr_t Arg4, uintptr_t Arg5, uintptr_t Arg6, @@ -216,12 +229,12 @@ namespace Tasking auxv_array.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}}); // Store auxillary vector - foreach (AuxiliaryVector var in auxv_array) + foreach (AuxiliaryVector av in auxv_array) { // Subtract the size of the auxillary vector Stack64 -= sizeof(Elf_auxv_t) / sizeof(uintptr_t); // Store the auxillary vector - POKE(Elf_auxv_t, Stack64) = var.archaux; + POKE(Elf_auxv_t, Stack64) = av.archaux; // TODO: Store strings to the stack } @@ -321,6 +334,8 @@ namespace Tasking TaskCompatibility Compatibility, bool ThreadNotReady) { + debug("+ %#lx", this); + assert(ctx != nullptr); assert(Architecture >= _ArchitectureMin); assert(Architecture <= _ArchitectureMax); @@ -348,12 +363,11 @@ namespace Tasking this->ExitCode = KILL_CRASH; if (ThreadNotReady) - this->Status = TaskStatus::Zombie; + this->State = TaskState::Waiting; else - this->Status = TaskStatus::Ready; + this->State = TaskState::Ready; - this->Memory = new Memory::MemMgr(this->Parent->PageTable, - this->Parent->memDirectory); + this->vma = new Memory::VirtualMemoryArea(this->Parent->PageTable); #if defined(a64) this->Registers.rip = EntryPoint; @@ -371,8 +385,7 @@ namespace Tasking case TaskExecutionMode::Kernel: { this->Security.IsCritical = true; - this->Stack = new Memory::StackGuard(false, - this->Parent->PageTable); + this->Stack = new Memory::StackGuard(false, this->vma); #if defined(a64) this->ShadowGSBase = @@ -403,14 +416,15 @@ namespace Tasking } case TaskExecutionMode::User: { - this->Stack = new Memory::StackGuard(true, - this->Parent->PageTable); + this->Stack = new Memory::StackGuard(true, this->vma); - gsTCB *gsT = (gsTCB *)this->Memory->RequestPages(TO_PAGES(sizeof(gsTCB))); + gsTCB *gsT = (gsTCB *)this->vma->RequestPages(TO_PAGES(sizeof(gsTCB))); - gsT->SyscallStack = - (uintptr_t)this->Memory->RequestPages(TO_PAGES(STACK_SIZE)) + - STACK_SIZE - 0x10; + gsT->ScPages = TO_PAGES(STACK_SIZE); + gsT->SyscallStackBase = this->vma->RequestPages(gsT->ScPages); + gsT->SyscallStack = (uintptr_t)gsT->SyscallStackBase + STACK_SIZE - 0x10; + debug("New syscall stack created: %#lx (base: %#lx) with gs base at %#lx", + gsT->SyscallStack, gsT->SyscallStackBase, gsT); gsT->TempStack = 0x0; gsT->t = this; @@ -488,25 +502,33 @@ namespace Tasking this->Registers.esp); #elif defined(aa64) #endif - debug("Created thread \"%s\"(%d) in process \"%s\"(%d)", + debug("Created %s thread \"%s\"(%d) in process \"%s\"(%d)", + this->Security.ExecutionMode == TaskExecutionMode::User ? "user" : "kernel", this->Name, this->ID, this->Parent->Name, this->Parent->ID); #endif - this->Info.SpawnTime = TimeManager->GetCounter(); + this->AllocatedMemory += sizeof(TCB); + this->AllocatedMemory += strlen(this->Parent->Name) + 1; + this->AllocatedMemory += sizeof(Memory::StackGuard); + this->Info.SpawnTime = TimeManager->GetCounter(); this->Parent->Threads.push_back(this); if (this->Parent->Threads.size() == 1 && - this->Parent->Status == Zombie && + this->Parent->State == Waiting && ThreadNotReady == false) { - this->Parent->Status = Ready; + this->Parent->State = Ready; + debug("Setting process \"%s\"(%d) to ready", + this->Parent->Name, this->Parent->ID); } } TCB::~TCB() { + debug("- %#lx", this); + /* Remove us from the process list so we don't get scheduled anymore */ std::vector &Threads = this->Parent->Threads; @@ -514,13 +536,13 @@ namespace Tasking Threads.end(), this)); - /* Free Name */ - delete[] this->Name; - /* Free CPU Stack */ delete this->Stack; /* Free all allocated memory */ - delete this->Memory; + delete this->vma; + + /* Free Name */ + delete[] this->Name; } } diff --git a/Tests/CPUID.cpp b/tests/cpuid.cpp similarity index 85% rename from Tests/CPUID.cpp rename to tests/cpuid.cpp index 289245ed..28f71a10 100644 --- a/Tests/CPUID.cpp +++ b/tests/cpuid.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/tests/lsof.cpp b/tests/lsof.cpp new file mode 100644 index 00000000..73301e81 --- /dev/null +++ b/tests/lsof.cpp @@ -0,0 +1,64 @@ +#ifdef DEBUG + +#include "t.h" + +#include "../kernel.h" + +using vfs::Node; +using vfs::NodeType; + +static int ShowOpenFiles = 0; + +void lsof() +{ + thisThread->Rename("Debug File List"); + thisThread->SetPriority(Tasking::Idle); + + while (ShowOpenFiles == 0) + CPU::Pause(); + + thisThread->SetPriority(Tasking::High); + + fs->Create("/dummy_lsof_file", NodeType::FILE); + fopen("/dummy_lsof_file", "r"); + + while (true) + { + while (ShowOpenFiles == 0) + CPU::Pause(); + + Video::ScreenBuffer *sb = Display->GetBuffer(0); + for (short i = 0; i < 500; i++) + { + for (short j = 0; j < 500; j++) + { + uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); + *Pixel = 0x222222; + } + } + + uint32_t tmpX, tmpY; + Display->GetBufferCursor(0, &tmpX, &tmpY); + Display->SetBufferCursor(0, 0, 0); + printf("\eF02C21Open Files (%ld):\e00AAAA\n", + TaskManager->GetProcessList().size()); + foreach (auto Proc in TaskManager->GetProcessList()) + { + if (!Proc) + continue; + + printf("%s:\n", Proc->Name); + + std::vector fds_array = + Proc->FileDescriptors->GetFileDescriptors(); + foreach (auto fd in fds_array) + printf(" %d: %s\n", fd.Descriptor, + fd.Handle->node->FullPath); + } + Display->SetBufferCursor(0, tmpX, tmpY); + if (!Config.BootAnimation) + Display->SetBuffer(0); + } +} + +#endif // DEBUG diff --git a/tests/macros.cpp b/tests/macros.cpp new file mode 100644 index 00000000..29596670 --- /dev/null +++ b/tests/macros.cpp @@ -0,0 +1,159 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifdef DEBUG + +#include +#include +#include +#include +#include + +#include +#include "../syscalls.h" + +/* static assert, no constructor needed */ + +#ifdef a64 +#if UINTPTR_MAX != UINT64_MAX +#error "uintptr_t is not 64-bit!" +#endif // UINTPTR_MAX != UINT64_MAX +#endif // a64 + +#ifdef a32 +#if UINTPTR_MAX != UINT32_MAX +#error "uintptr_t is not 32-bit!" +#endif // UINTPTR_MAX != UINT32_MAX +#endif // a32 + +#ifdef aa64 +#if UINTPTR_MAX != UINT64_MAX +#error "uintptr_t is not 64-bit!" +#endif // UINTPTR_MAX != UINT64_MAX +#endif // aa64 + +void TestSeekMacros() +{ + static_assert(sc_SEEK_SET == SEEK_SET); + static_assert(sc_SEEK_CUR == SEEK_CUR); + static_assert(sc_SEEK_END == SEEK_END); +} + +__constructor void TestMacros() +{ + { + int a = TO_PAGES(4096); + int b = FROM_PAGES(1); + + debug("a: 4096 -> %d", a); + debug("b: a -> %d", b); + + if (a != 1) + { + error("t1: TO_PAGES is not equal to 1"); + inf_loop; + } + + if (b != 4096) + { + error("t1: FROM_PAGES is not equal to 4096"); + inf_loop; + } + } + + { + int a = TO_PAGES(4097); + int b = FROM_PAGES(2); + + debug("a: 4097 -> %d", a); + debug("b: a -> %d", b); + + if (a != 2) + { + error("t2: TO_PAGES is not equal to 2"); + inf_loop; + } + + if (b != 8192) + { + error("t2: FROM_PAGES is not equal to 8192"); + inf_loop; + } + } + + { + int a = 10; + assert(a == 10); + + const char *str = "Hello"; + assert(str != nullptr && str[0] == 'H'); + + bool flag = false; + assert(!flag); + } + + debug("-------------------------"); + + { + uint64_t bytes = PAGE_SIZE; + uint64_t pgs = 1; + + for (int i = 0; i < 128; i++) + { + uint64_t cnv_to_pgs = TO_PAGES(bytes); + uint64_t cnv_from_pgs = FROM_PAGES(pgs); + + if (cnv_to_pgs != pgs) + { + error("TO_PAGES is not equal to %d (pages: %d)", pgs, cnv_to_pgs); + inf_loop; + } + + if (cnv_from_pgs != bytes) + { + error("FROM_PAGES is not equal to %d (bytes: %d)", bytes, cnv_from_pgs); + inf_loop; + } + + bytes += PAGE_SIZE; + pgs++; + } + } + + { + debug("Testing ROUND_UP and ROUND_DOWN"); + int x = 0x101; + int y = 0x100; + int result; + + result = ROUND_UP(x, y); + if (result != 0x200) + { + error("ERROR: ROUND_UP failed: %d != 0x200", result); + inf_loop; + } + + result = ROUND_DOWN(x, y); + if (result != 0x100) + { + error("ERROR: ROUND_DOWN failed: %d != 0x100", result); + inf_loop; + } + } +} + +#endif // DEBUG diff --git a/Tests/MemoryAllocation.cpp b/tests/mem_allocs.cpp similarity index 88% rename from Tests/MemoryAllocation.cpp rename to tests/mem_allocs.cpp index 4be270f8..4c1fd761 100644 --- a/Tests/MemoryAllocation.cpp +++ b/tests/mem_allocs.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/Tests/MemoryOperations.cpp b/tests/mem_ops.cpp similarity index 77% rename from Tests/MemoryOperations.cpp rename to tests/mem_ops.cpp index 3b16a085..2edb6df5 100644 --- a/Tests/MemoryOperations.cpp +++ b/tests/mem_ops.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/Tests/RandomNumberGenerator.cpp b/tests/rng.cpp similarity index 73% rename from Tests/RandomNumberGenerator.cpp rename to tests/rng.cpp index 0f6eb13c..3f227a6a 100644 --- a/Tests/RandomNumberGenerator.cpp +++ b/tests/rng.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/Tests/std.cpp b/tests/std.cpp similarity index 58% rename from Tests/std.cpp rename to tests/std.cpp index 7ce27771..f09d6b38 100644 --- a/Tests/std.cpp +++ b/tests/std.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/Tests/String.cpp b/tests/std_string.cpp similarity index 79% rename from Tests/String.cpp rename to tests/std_string.cpp index ac8560ec..8163cc52 100644 --- a/Tests/String.cpp +++ b/tests/std_string.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/tests/t.h b/tests/t.h new file mode 100644 index 00000000..59322fe2 --- /dev/null +++ b/tests/t.h @@ -0,0 +1,35 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_non_constructor_tests_H__ +#define __FENNIX_KERNEL_non_constructor_tests_H__ +#ifdef DEBUG + +#include +#include + +void TestString(); +void Test_std(); +void TestMemoryAllocation(); +void tasking_test_fb(); +void tasking_test_mutex(); +void lsof(); +void TaskMgr(); +void TreeFS(vfs::Node *node, int Depth); + +#endif // DEBUG +#endif // !__FENNIX_KERNEL_non_constructor_tests_H__ diff --git a/tests/tasking_mutex.cpp b/tests/tasking_mutex.cpp new file mode 100644 index 00000000..4c6ef104 --- /dev/null +++ b/tests/tasking_mutex.cpp @@ -0,0 +1,50 @@ +#ifdef DEBUG + +#include "t.h" + +#include "../kernel.h" + +#include +std::mutex test_mutex; + +void mutex_test_long() +{ + while (true) + { + test_mutex.lock(); + debug("Long Thread %d got mutex", + thisThread->ID); + // TaskManager->Sleep(2000); + test_mutex.unlock(); + } +} + +void mutex_test() +{ + while (true) + { + test_mutex.lock(); + debug("Thread %d got mutex", + thisThread->ID); + // TaskManager->Sleep(200); + test_mutex.unlock(); + } +} + +void tasking_test_mutex() +{ + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test_long)); + TaskManager->Yield(); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test)); + ilp; +} + +#endif // DEBUG diff --git a/tests/tasking_rgb.cpp b/tests/tasking_rgb.cpp new file mode 100644 index 00000000..67dfc079 --- /dev/null +++ b/tests/tasking_rgb.cpp @@ -0,0 +1,96 @@ +#ifdef DEBUG + +#include "t.h" + +#include "../kernel.h" + +BootInfo::FramebufferInfo fb_ptr{}; +void tasking_test_fb_loop(int x, int y, uint32_t color) +{ + assert(fb_ptr.BaseAddress != nullptr); + while (true) + { + for (int i = 0; i < 16; i++) + { + uint32_t *Pixel = (uint32_t *)((uintptr_t)fb_ptr.BaseAddress + + ((y + i) * fb_ptr.Width + x) * + (fb_ptr.BitsPerPixel / 8)); + for (int j = 0; j < 16; j++) + { + *Pixel = color; + Pixel++; + } + } + } +} + +void TTfbL_red() { tasking_test_fb_loop(0, 0, 0xFFFF0000); } +void TTfbL_green() { tasking_test_fb_loop(16, 0, 0xFF00FF00); } +void TTfbL_blue() { tasking_test_fb_loop(32, 0, 0xFF0000FF); } +void TTfbL_white() { tasking_test_fb_loop(48, 0, 0xFFFFFFFF); } +void TTfbL_gray() { tasking_test_fb_loop(64, 0, 0xFF888888); } +void TTfbL_red_neg() { tasking_test_fb_loop(0, 0, 0xFF00FFFF); } +void TTfbL_green_neg() { tasking_test_fb_loop(16, 0, 0xFFFF00FF); } +void TTfbL_blue_neg() { tasking_test_fb_loop(32, 0, 0xFFFFFF00); } +void TTfbL_white_neg() { tasking_test_fb_loop(48, 0, 0xFF000000); } +void TTfbL_gray_neg() { tasking_test_fb_loop(64, 0, 0xFF777777); } +void TTfbL_rainbow_fct(int offset) +{ + while (true) + { + /* AARRGGBB*/ + static uint32_t color = 0xFF000000; + + for (int i = 0; i < 64; i++) + { + uint32_t *Pixel = (uint32_t *)((uintptr_t)fb_ptr.BaseAddress + + ((offset + i) * fb_ptr.Width) * + (fb_ptr.BitsPerPixel / 8)); + for (int j = 0; j < 16; j++) + { + *Pixel = color; + Pixel++; + } + } + if (color >= 0xFFFFFFFF) + color = 0xFF000000; + color++; + } +} +void TTfbL_rainbow_idle() { TTfbL_rainbow_fct(16); } +void TTfbL_rainbow_low() { TTfbL_rainbow_fct(80); } +void TTfbL_rainbow_norm() { TTfbL_rainbow_fct(144); } +void TTfbL_rainbow_high() { TTfbL_rainbow_fct(208); } +void TTfbL_rainbow_crit() { TTfbL_rainbow_fct(272); } +void tasking_test_fb() +{ + fb_ptr = Display->GetFramebufferStruct(); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_red)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_green)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_blue)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_white)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_gray)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_red_neg)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_green_neg)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_blue_neg)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_white_neg)); + TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_gray_neg)); + + { + CriticalSection cs; /* Start all threads at the same time */ + auto tti = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_idle)); + auto ttl = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_low)); + auto ttn = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_norm)); + auto tth = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_high)); + auto ttc = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_crit)); + + tti->SetPriority(Tasking::TaskPriority::Idle); + ttl->SetPriority(Tasking::TaskPriority::Low); + ttn->SetPriority(Tasking::TaskPriority::Normal); + tth->SetPriority(Tasking::TaskPriority::High); + ttc->SetPriority(Tasking::TaskPriority::Critical); + } + // Exit +} + +#endif // DEBUG diff --git a/tests/taskmgr.cpp b/tests/taskmgr.cpp new file mode 100644 index 00000000..f71e85da --- /dev/null +++ b/tests/taskmgr.cpp @@ -0,0 +1,169 @@ +#ifdef DEBUG + +#include "t.h" + +#include "../kernel.h" + +const char *Statuses[] = { + "FF0000", /* Unknown */ + "AAFF00", /* Ready */ + "00AA00", /* Running */ + "FFAA11", /* Sleeping */ + "FFAA0F", /* Blocked */ + "FFAA0F", /* Stopped */ + "FFAA5F", /* Waiting */ + + "FF0088", /* Zombie */ + "FF0000", /* Terminated */ +}; + +const char *StatusesSign[] = { + "Unknown", + "Ready", + "Run", + "Sleep", + "Block", + "Stop", + "Wait", + + "Zombie", + "Terminated", +}; + +const char *SuccessSourceStrings[] = { + "Unknown", + "GetNextAvailableThread", + "GetNextAvailableProcess", + "SchedulerSearchProcessThread", +}; + +void TaskMgr_Dummy100Usage() +{ + while (1) + ; +} + +void TaskMgr_Dummy0Usage() +{ + while (1) + TaskManager->Sleep(1000000); +} + +uint64_t GetUsage(uint64_t OldSystemTime, Tasking::TaskInfo *Info) +{ + /* https://github.com/reactos/reactos/blob/560671a784c1e0e0aa7590df5e0598c1e2f41f5a/base/applications/taskmgr/perfdata.c#L347 */ + if (Info->OldKernelTime || Info->OldUserTime) + { + uint64_t SystemTime = TimeManager->GetCounter() - OldSystemTime; + uint64_t CurrentTime = Info->KernelTime + Info->UserTime; + uint64_t OldTime = Info->OldKernelTime + Info->OldUserTime; + uint64_t CpuUsage = (CurrentTime - OldTime) / SystemTime; + CpuUsage = CpuUsage * 100; + + // debug("CurrentTime: %ld OldTime: %ld Time Diff: %ld Usage: %ld%%", + // CurrentTime, OldTime, SystemTime, CpuUsage); + + Info->OldKernelTime = Info->KernelTime; + Info->OldUserTime = Info->UserTime; + return CpuUsage; + } + Info->OldKernelTime = Info->KernelTime; + Info->OldUserTime = Info->UserTime; + return 0; +} + +static int ShowTaskManager = 0; + +void TaskMgr() +{ + thisThread->Rename("Debug Task Manager"); + thisThread->SetPriority(Tasking::Idle); + + while (ShowTaskManager == 0) + CPU::Pause(); + + thisThread->SetPriority(Tasking::High); + + TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy100Usage))->Rename("Dummy 100% Usage"); + TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy0Usage))->Rename("Dummy 0% Usage"); + + while (true) + { + while (ShowTaskManager == 0) + CPU::Pause(); + + static int sanity = 0; + Video::ScreenBuffer *sb = Display->GetBuffer(0); + for (short i = 0; i < 1000; i++) + { + for (short j = 0; j < 500; j++) + { + uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); + *Pixel = 0x222222; + } + } + + uint32_t tmpX, tmpY; + Display->GetBufferCursor(0, &tmpX, &tmpY); + Display->SetBufferCursor(0, 0, 0); + printf("\eF02C21Task Manager\n"); + static uint64_t OldSystemTime = 0; + foreach (auto Proc in TaskManager->GetProcessList()) + { + if (!Proc) + continue; + int State = Proc->State.load(); + uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info); +#if defined(a64) + printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n", + Statuses[State], Proc->Name, StatusesSign[State], + ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime); +#elif defined(a32) + printf("\e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld)\n", + Statuses[State], Proc->Name, StatusesSign[State], + ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime); +#elif defined(aa64) +#endif + + foreach (auto Thd in Proc->Threads) + { + if (!Thd) + continue; + State = Thd->State.load(); + uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info); +#if defined(a64) + printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC", + Statuses[State], Thd->Name, StatusesSign[State], ThreadCpuUsage, Thd->Info.KernelTime, + Thd->Info.UserTime, Thd->Registers.rip, + Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.rip) : "unknown"); +#elif defined(a32) + printf(" \e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld, IP: \e24FF2B%#x \eEDFF24%s\e00AAAA)\n\eAABBCC", + Statuses[State], Thd->Name, StatusesSign[State], ThreadCpuUsage, Thd->Info.KernelTime, + Thd->Info.UserTime, Thd->Registers.eip, + Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.eip) : "unknown"); +#elif defined(aa64) +#endif + } + } + OldSystemTime = TimeManager->GetCounter(); +#if defined(a64) + register uintptr_t CurrentStackAddress asm("rsp"); + printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); +#elif defined(a32) + register uintptr_t CurrentStackAddress asm("esp"); + printf("Sanity: %d, Stack: %#x", sanity++, CurrentStackAddress); +#elif defined(aa64) + register uintptr_t CurrentStackAddress asm("sp"); + printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); +#endif + if (sanity > 1000) + sanity = 0; + Display->SetBufferCursor(0, tmpX, tmpY); + if (!Config.BootAnimation) + Display->SetBuffer(0); + + TaskManager->Sleep(100); + } +} + +#endif // DEBUG diff --git a/tests/treefs.cpp b/tests/treefs.cpp new file mode 100644 index 00000000..82f74886 --- /dev/null +++ b/tests/treefs.cpp @@ -0,0 +1,21 @@ +#ifdef DEBUG + +#include "t.h" + +#include "../kernel.h" + +void TreeFS(vfs::Node *node, int Depth) +{ + return; + foreach (auto Chld in node->Children) + { + printf("%*c %s\eFFFFFF\n", Depth, ' ', Chld->Name); + + if (!Config.BootAnimation) + Display->SetBuffer(0); + TaskManager->Sleep(100); + TreeFS(Chld, Depth + 1); + } +} + +#endif // DEBUG diff --git a/Tests/TypeSize.cpp b/tests/types_sizes.cpp similarity index 87% rename from Tests/TypeSize.cpp rename to tests/types_sizes.cpp index 63a81b29..ee59048c 100644 --- a/Tests/TypeSize.cpp +++ b/tests/types_sizes.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #ifdef DEBUG diff --git a/Virtualization/IsVirtualizedEnvironment.cpp b/virtualization/vm_detect.cpp similarity index 78% rename from Virtualization/IsVirtualizedEnvironment.cpp rename to virtualization/vm_detect.cpp index 864290cb..80e15658 100644 --- a/Virtualization/IsVirtualizedEnvironment.cpp +++ b/virtualization/vm_detect.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include @@ -26,7 +26,9 @@ bool DetectByHypervisor() { const char *Hypervisor = CPU::Hypervisor(); - if (strcmp(Hypervisor, x86_CPUID_VENDOR_VMWARE) == 0) + if (strcmp(Hypervisor, "None") == 0) + return false; + else if (strcmp(Hypervisor, x86_CPUID_VENDOR_VMWARE) == 0) goto Yes; else if (strcmp(Hypervisor, x86_CPUID_VENDOR_XENHVM) == 0) goto Yes; @@ -145,6 +147,8 @@ bool DetectByCPUID() bool DetectByHPET() { + assert(PowerManager == nullptr); + void *acpi = PowerManager->GetACPI(); if (!acpi) return false; @@ -173,7 +177,15 @@ Yes: bool IsVirtualizedEnvironment() { - bool IsVM = false; + static bool IsVM = false; + + static int _check = 0; + if (!_check++) + { + debug("Virtualized environment: %s", + IsVM ? "Yes" : "No"); + return IsVM; + } debug("Detecting virtualized environment...");