diff --git a/.github/workflows/flawfinder.yml b/.github/workflows/flawfinder.yml index 8b86923..dfa6d33 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 7379e12..6ebb98d 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 8ea597c..972e73e 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 0f69fa8..8fb6c52 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 857cea0..0000000 --- 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 00c00e4..0000000 --- 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 aea8637..0000000 --- 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 f6c89b9..0000000 --- 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 0349abc..0000000 --- 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 087ee5f..0000000 --- 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 2509ccd..0000000 --- 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 511355d..0000000 --- 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 5e9efa9..0000000 --- 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 a1ad5dd..0000000 --- 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 f0f4682..0000000 --- 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 56fff32..0000000 --- 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 2509ccd..0000000 --- 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 5e9efa9..0000000 --- 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 cc9c500..0000000 --- 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 0000000..703a9a2 --- /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 44da090..0000000 --- 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 5a070f4..0000000 --- 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 5aa3ddb..0000000 --- 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 280dace..0000000 --- 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 281391f..0000000 --- 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 98fe0c9..0000000 --- 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 09cfdcf..0000000 --- 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 9311aab..0000000 --- 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 188ef73..0000000 --- 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 4636726..0000000 --- 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 b80d074..0000000 --- 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 f8b46ad..0000000 --- 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 9c2b5a4..0000000 --- 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 48884ef..0000000 --- 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 a506f2c..0000000 --- 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 61b5e11..0000000 --- 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 a2ef85f..0000000 --- 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 0a9fc11..0000000 --- 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 b1d7e76..86c9fc6 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 56a84fb..0000000 --- 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 e08ea66..0000000 --- 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 086a67d..0000000 --- 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 1630149..0000000 --- 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 6908189..0000000 --- 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 fb4894d..0000000 --- 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 b441e44..0000000 --- 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 0000000..3820f99 --- /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 06a6c1f..0000000 --- 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 741df05..0000000 --- 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 8fe4826..0000000 --- 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 66a77c3..0000000 --- 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 3606114..0000000 --- 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 7541faa..0000000 --- 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 2c00a80..0000000 --- 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 8344ab2..0000000 --- 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 c0ddf66..0000000 --- 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 677430f..0000000 --- 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 d738021..0000000 --- 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 a2c8766..0000000 --- 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 2e72275..0000000 --- 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 64ca4f0..0000000 --- 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 0a07607..0000000 --- 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 a1de40e..0000000 --- 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 0000000..88190c2 --- /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 92e60c6..0000000 --- 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 e4ab1a9..0000000 --- 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 622ac2d..0000000 --- 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 6d0ce80..0000000 --- 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 5a17ab2..0000000 --- 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 8d8dd54..0000000 --- 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 f15df7e..6a0e6bf 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 d514d5a..0000000 --- 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 98b59af..0000000 --- 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 a55f99d..0000000 --- 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 ab33674..0000000 --- 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 46593bc..0000000 --- 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 7a4b2bc..0000000 --- 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 53fab55..0000000 --- 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 97736be..0000000 --- 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 e1ba8c4..0000000 --- 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 0000000..9f714b4 --- /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 089e9fa..0000000 --- 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 9525b5c..0000000 --- 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 0000000..7f6454d --- /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 0000000..7b0fb75 --- /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 0000000..d1c471e --- /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 0000000..bfd3461 --- /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 0000000..4530a6b --- /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 0000000..692d60b --- /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 d90fc64..3cf7e64 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 2895b2e..258e17e 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 0000000..b4e8afc --- /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 0000000..309d219 --- /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 337a831..6fc9de8 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 b2d8643..d0c05aa 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 0000000..a91af89 --- /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 5217f10..f81e8e3 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 4733dd0..fd6caf1 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 83f972c..e85e20a 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 fc67058..5d1d1bb 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 2c2d3ad..04ed992 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 9b1b5eb..c42299e 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 34aae7f..aaf2ca5 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 4542472..2d0ff14 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 e724613..2b0263d 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 afc6d3a..b87b78a 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 0000000..5115f16 --- /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 89ecdd0..600072c 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 fb42772..99d0284 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 0000000..14cdd2c --- /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 5513b75..03326a3 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 fb00ab7..a7ab204 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 a984886..4e75052 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 389b42c..75fc017 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 0000000..692d60b --- /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 0000000..bd3cc78 --- /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 41c5168..a50e622 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 44f6415..5521c8c 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 0000000..b4e8afc --- /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 02e8ded..b274412 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 1ae8ab8..b858660 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 fc67058..5d1d1bb 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 a21aae4..3df5bf4 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 a39b9e7..dd17cfa 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 a3001fd..6f969d9 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 dd4167e..a81cb5f 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 43ed227..2f5015e 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 e5b6d87..ad08cb3 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 9e2a149..aed7520 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 50055e0..78c2ea7 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 b2a5991..ab2f540 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 fb0e5f1..f0d6013 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 4913e60..7e8cb44 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 f1176ed..61fcff8 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 d5c9da3..a286a37 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 0000000..8e072cc --- /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 0000000..0b04ddb --- /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 5f5cf6e..c6c7021 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 6b17476..c3b1f9b 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 3c7ae73..fa620ae 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 b66c9a2..9c7af0e 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 ebd21f2..5c5e2a9 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 19cbdcb..97017db 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 0000000..403a02d --- /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 28a0215..322df1c 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 a03f951..4c9ca5f 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 0b23cf5..80599f8 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 c2f64f7..83a4ad3 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 026177f..8cecea8 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 0000000..886beb8 --- /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 0000000..66dabfb --- /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 3af8ffe..e7df117 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 0000000..aa0b69e --- /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 d285b69..6bc302b 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 a996ea1..e3299fa 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 7c12dc1..1d20e52 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 0000000..83a6813 --- /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 0000000..06f0210 --- /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 0000000..2e4a393 --- /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 9fee239..44cdbc9 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 23fcc97..bc38d1f 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 15063bc..be829ae 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 db59db7..d3dc459 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 98270e6..9d9c3dd 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 e95f84f..b9258e3 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 0ce86d0..08e6078 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 0000000..ef954b4 --- /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 0000000..30995b8 --- /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 0000000..78c533b --- /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 0000000..1d99fca --- /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 0000000..8598198 --- /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 0000000..1f3e47a --- /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 0000000..30d3bb8 --- /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 0000000..f5bac93 --- /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 0000000..d2d49a6 --- /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 0000000..3427dd4 --- /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 0000000..f3469de --- /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 f1a342a..1176059 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 45b10fc..4f0c2f0 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 bd51308..a0df724 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 9d7159f..a28bacf 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 c2f31cb..92af5d3 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 ee73d99..f3fce77 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 4dd444b..fa87d4b 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 bcca7e2..5079fc8 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 acb66fe..1b7dc02 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 b797052..0e77986 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 64ab488..cf8ae06 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 cdbd6b7..3460b8f 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 5c5ad36..34f6f35 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 cb3e622..00df0ee 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 9656a0e..070a14c 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 4d8aab1..66373f2 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 730f9f2..02ad1e8 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 b6a2aa0..65413d2 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 ea4c896..a7cd724 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 dbfab36..fd6b35c 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 e386b60..202231d 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 b2027c5..249d156 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 071bd7f..b3af84a 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 4e9167d..248e683 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 c046d75..a874105 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 8f6f617..6a28a43 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 d8f38b6..68275e5 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 28e28da..251d6fc 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 13c206e..a37e19f 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 f724b35..a6fed5c 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 cf95860..0390285 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 0c737e7..148a9f2 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 14ffaa4..66293e7 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 daab964..597f999 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 3d7e071..793b01d 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 83db73f..ea44bea 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 e46d83d..5e6f90e 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 150ca63..1cf42ba 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 0b749e4..174b7ad 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 eeb56b4..ffcb45b 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 5a8fb45..2f770c2 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 a078cc1..3950116 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 23d6c69..36f390e 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 79e8096..4ca0970 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 c332d57..ab4e710 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 57d54e4..fb40c90 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 26bab12..0000000 --- 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 58a0e38..f10b654 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 abc5c27..300fd4b 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 878aadf..6f3af05 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 e0475b1..5255ba8 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 976fbce..902fff9 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 24793cb..dab2360 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 7781a40..30a083e 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 994df1d..9bfb3a9 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 0000000..0024105 --- /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 94f2e5f..9f66336 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 72ec83d..ff12c36 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 f123860..e4f5c26 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 fc47ea7..4de9c43 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 99affe5..d0be168 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 e6bfc30..c5b90ab 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 2b6df6b..85ba19a 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 5a7a3f5..9831106 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 31ea0e4..997d230 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 710cc20..65e5ac3 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 382d47a..9a8a8cc 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 c8abb76..751485f 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 0000000..b80c4fd --- /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 0000000..2543df0 --- /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 0000000..33aca97 --- /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 0000000..a709f40 --- /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 0000000..2b295d2 --- /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 0000000..83c93c3 --- /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 0000000..b007dc0 --- /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 0000000..bd11e83 --- /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 0000000..7c62ca6 --- /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 0000000..f338a52 --- /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 4b3fe94..60d2874 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 6ea082a..c97d2e5 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 ed467cf..82f54e1 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 8cff0bb..9eb03bf 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 0030b5b..cbf24a0 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 7611a5c..fed57c3 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 9e4dbde..e4b9b26 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 820a289..cfd2412 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 f67f343..b910389 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 04a5675..92aafbe 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 b9074f4..2112abe 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 2ac5bb1..129a91b 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 000198b..83008aa 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 12d7d6e..1278755 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 a0b9d21..0c0881b 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 be24192..88f2762 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 50aa4fa..7dd941d 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 0000000..18884d8 --- /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 577084f..8556c33 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 d29f221..56596b9 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 d9e2159..cd7bf26 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 419af1e..072b213 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 4f5a395..c6991c2 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 60ac230..c789911 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 6da7e84..8e27174 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 9d02fc1..9806556 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 5648c51..4cbef0f 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 327957f..a4323be 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 55e4f7d..00a7e3c 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 3244430..51678ae 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 932851d..54c0b04 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 c17ea34..18668ed 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 f6852ff..d0fe871 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 b1a7f20..fe0b0b7 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 178e145..8e46836 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 3c5095c..1114b46 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 23fe896..96f642c 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 7544596..f36b0a6 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 ec7b1a4..666c05f 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 e2bdcea..95a5298 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 7d61f6a..ed24bdb 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 18252df..f96284e 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 2b255b0..675412b 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 aec2bc3..672e9c1 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 56bc215..4f82fcd 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 1a32a8e..61e32f7 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 eadf39e..12c6a4e 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 2de7557..5869cb0 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 94c4d58..f6bc275 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 b243c38..5f35d50 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 9bfab12..f0dd0ad 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 345f682..84ae6e7 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 12814c4..518fdfe 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 f079bb0..46d7b05 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 f346b21..1f02863 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 e03e3be..270d58c 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 732ac6d..7882986 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 3d95cab..84cc7ad 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 771861f..928ea3f 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 2834743..0330644 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 ecb4e58..909d60f 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 bc6c48f..b8b900e 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 2ff2d38..08f651d 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 eb48b44..9da4e6f 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 447b6e1..1093506 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 4a129ef..0def563 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 9bb9ee5..0cac610 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 fd50c1e..0c04855 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 d46b2f2..8c44540 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 9f2fbbb..f2b21e4 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 93da616..105c098 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 9fb14d0..d22dab0 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 0000000..c051a6e --- /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 05f57fc..f82a4a2 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 2d4fac7..b0206d4 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 0000000..b70eb8d --- /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 9ec79d7..d120022 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 0000000..eefeb73 --- /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 0000000..f8d2668 --- /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 0000000..f4aa2e9 --- /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 0000000..20dcb9d --- /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 0000000..76879a7 --- /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 0000000..93dd8a2 --- /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 0000000..38c3d14 --- /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 0000000..92f0017 --- /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 0000000..ddf66e9 --- /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 b7c73b7..1b2e51a 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 0000000..fcc2ac1 --- /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 0000000..a9da545 --- /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 0000000..0d3acea --- /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 0000000..4076e44 --- /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 087eba9..e4e59a7 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 3aab5b5..ff85b37 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 0000000..ba2a2ce --- /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 675142e..0073903 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 0000000..aa3e7e9 --- /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 f4e5ade..9fd969b 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 4deb16a..1ca4821 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 2e1755c..435f1ef 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 0000000..a4b5071 --- /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 b2b0c62..643e388 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 4e909e1..d5ebde1 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 942dd8d..1417da5 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 0000000..aaa8107 --- /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 c7658f3..a4e40a0 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 0000000..46d5b2f --- /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 d6048c7..cb37dfd 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 0000000..30e2a5b --- /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 3b42b80..af04039 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 5a11b64..36e7198 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 d43b394..8b71e76 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 0000000..be514bf --- /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 37681da..1baff3b 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 0000000..a0eb245 --- /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 8063997..b39d8ee 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 642a738..d8f87b6 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 64bf496..9dda165 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 156ad63..5ffae2e 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 8466238..ae62521 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 0000000..6406f80 --- /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 e7d15a6..3b5330b 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 0000000..c8fd420 --- /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 55550bd..bf7be3c 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 6e73e5c..b6d1ad4 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 49ab577..ffb4c83 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 5291e93..24d449e 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 0000000..e41f40a --- /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 4323a6b..d843057 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 f565a1a..4c24cb3 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 c8ceec7..a7fedd2 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 01cc24b..eee1933 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 7703091..cf801e6 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 86bea91..2e87045 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 a56af7b..9ae895e 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 16b0f6f..031949c 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 64bc3f1..3f601da 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 8c4f63e..354d376 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 0000000..2edac75 --- /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 3f0380a..db93051 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 0000000..98c46ad --- /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 eb5b87d..265012f 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 3851a9e..1bc3788 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 562d439..c6075fc 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 9284c96..65d9b06 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 0043de2..229bee4 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 d11433d..9fe7717 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 0000000..61b7fc4 --- /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 bd6d8d0..3791b08 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 ba5c3b3..a12f83e 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 b5277f6..c3d4866 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 0000000..afd3d4b --- /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 7fc30cb..d6279ec 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 0000000..fc67980 --- /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 0000000..2223d29 --- /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 0000000..0c062f6 --- /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 0000000..8f7fc4b --- /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 0000000..be170b2 --- /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 0000000..435acd7 --- /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 0000000..c1eac3c --- /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 0000000..1a7131e --- /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 0000000..c8168d0 --- /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 e787f12..c9bf0ce 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 0000000..5e5e888 --- /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 0000000..7580dd3 --- /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 c68b775..fed4f95 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 27b3784..803bd81 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 0000000..e69de29 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 7d81d7d..ab6620f 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 0000000..340d5c1 --- /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 0000000..8410625 --- /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 0000000..a1e0ac3 --- /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 0000000..116a95a --- /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 0000000..555409b --- /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 0000000..9f04625 --- /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 0000000..7ca6dfa --- /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 0000000..fb42d97 --- /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 0000000..f5ab1d3 --- /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 0000000..99d67f7 --- /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 0000000..109ef28 --- /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 0000000..7c446aa --- /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 0000000..d077a57 --- /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 e1d9784..f00cd66 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 870b7ec..da0b513 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 48f87fa..1a990a2 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 84dadef..434d2c0 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 3653af8..1a52f00 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 289245e..28f71a1 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 0000000..73301e8 --- /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 0000000..2959667 --- /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 4be270f..4c1fd76 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 3b16a08..2edb6df 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 0f6eb13..3f227a6 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 7ce2777..f09d6b3 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 ac8560e..8163cc5 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 0000000..59322fe --- /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 0000000..4c6ef10 --- /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 0000000..67dfc07 --- /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 0000000..f71e85d --- /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 0000000..82f7488 --- /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 63a81b2..ee59048 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 864290c..80e1565 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...");