This commit is contained in:
antifallobst 2023-02-05 14:39:35 +01:00
parent 972174054b
commit 60cece9afb
26 changed files with 894 additions and 28 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
build build
cmake-build-debug cmake-build-debug
.idea .idea
noxos.log

View File

@ -1,7 +1,7 @@
# NoxOS # NoxOS
## Copyright / License ## Copyright / License
Copyright (C) Antifallobst <antifallobst@systemausfall.org> Copyright (C) 2023 Antifallobst <antifallobst@systemausfall.org>
NoxOS is free software: NoxOS is free software:
you can redistribute it and/or modify it under the terms of the GNU General Public License you can redistribute it and/or modify it under the terms of the GNU General Public License
@ -15,4 +15,7 @@ See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. You should have received a copy of the GNU General Public License along with this program.
If not, see <https://www.gnu.org/licenses/>. If not, see <https://www.gnu.org/licenses/>.
## Contribution Welcome :D
Install instructions and Code Documentation can be found in the [wiki](https://codeberg.org/antifallobst/noxos/wiki/).
If you want to contribute, filtering the [issues](https://codeberg.org/antifallobst/noxos/issues/) for the `Good First Issue` label would be a good way to start :)

View File

@ -51,23 +51,20 @@ generate_image() {
-efi-boot-part --efi-boot-image --protective-msdos-label \ -efi-boot-part --efi-boot-image --protective-msdos-label \
iso -o noxos.iso iso -o noxos.iso
./limine/limine-deploy noxos.iso
rm -rfv iso rm -rfv iso
cd .. cd ..
echo "" echo ""
} }
emulate() {
qemu-system-x86_64 -cdrom build/noxos.iso -chardev stdio,id=log,logfile=noxos.log -serial chardev:log
}
echo "!=====[ NoxOS build script ]=====!" echo "!=====[ NoxOS build script ]=====!"
workspace_setup workspace_setup
kernel_build kernel_build
[ ! -d "build/limine" ] && limine_install [ ! -d "build/limine" ] && limine_install
generate_image generate_image
emulate
echo "!=====[ Finished ]=====!" echo "!=====[ Finished ]=====!"

View File

@ -11,7 +11,7 @@ file(GLOB_RECURSE kernel_inc "**/*.h")
file(GLOB_RECURSE kernel_src_asm "**/*.asm") file(GLOB_RECURSE kernel_src_asm "**/*.asm")
target_compile_options(kernel PRIVATE -fno-stack-protector -fno-stack-check -mno-red-zone -ffreestanding -m64 -march=x86-64 -mabi=sysv) target_compile_options(kernel PRIVATE -g -fno-stack-protector -fno-stack-check -mno-red-zone -ffreestanding -m64 -march=x86-64 -mabi=sysv)
target_link_options(kernel PRIVATE -nostdlib -static -T "${CMAKE_CURRENT_LIST_DIR}/kernel.ld") target_link_options(kernel PRIVATE -nostdlib -static -T "${CMAKE_CURRENT_LIST_DIR}/kernel.ld")
enable_language(ASM_NASM) enable_language(ASM_NASM)

View File

@ -20,11 +20,10 @@
#include "limine.h" #include "limine.h"
typedef struct { typedef struct {
struct limine_framebuffer* framebuffer; struct limine_framebuffer_response* framebuffer;
struct limine_terminal* terminal; struct limine_terminal_response* terminal;
struct limine_memmap_entry** memory_map; struct limine_memmap_response* memory_map;
uint64_t memory_map_size; void* rsdp;
void* rsdp;
} boot_info_T; } boot_info_T;
#endif //NOX_BOOT_INFO_H #endif //NOX_BOOT_INFO_H

View File

@ -0,0 +1,24 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_MEMORY_MAP_H
#define NOX_MEMORY_MAP_H
#include "utils/stdtypes.h"
#include "boot/boot_info.h"
uint64_t memory_map_get_total_memory_size(boot_info_T* boot_info);
#endif //NOX_MEMORY_MAP_H

View File

@ -0,0 +1,43 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_PAGE_FRAME_H
#define NOX_PAGE_FRAME_H
#include "utils/stdtypes.h"
#include "utils/bitmap.h"
#include "boot/boot_info.h"
#define PFRAME_SIZE 4096 // The size of a page frame
typedef struct {
uint64_t free_memory;
uint64_t reserved_memory;
uint64_t used_memory;
uint64_t page_bitmap_index;
bitmap_T page_bitmap;
bool blocked;
} page_frame_manager_T;
void pframe_manager_init (boot_info_T* boot_info);
void pframe_reserve (void* address);
void pframe_reserve_multi (void* address, uint32_t n);
void pframe_unreserve (void* address);
void pframe_unreserve_multi (void* address, uint32_t n);
void pframe_free (void* address);
void pframe_free_multi (void* address, uint32_t n);
void* pframe_request ();
#endif //NOX_PAGE_FRAME_H

65
kernel/inc/platform/cpu.h Normal file
View File

@ -0,0 +1,65 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_CPU_H
#define NOX_CPU_H
#include "utils/stdtypes.h"
typedef enum {
CPU_FLAG_CARRY = 0,
CPU_FLAG_PARITY = 2,
CPU_FLAG_AUXILIARY = 4,
CPU_FLAG_ZERO = 6,
CPU_FLAG_SIGN = 7,
CPU_FLAG_TRAP = 8,
CPU_FLAG_INTERRUPT_ENABLE = 9,
CPU_FLAG_DIRECTION = 10,
CPU_FLAG_OVERFLOW = 11,
CPU_FLAG_IO_PRIVILEGE_0 = 12,
CPU_FLAG_IO_PRIVILEGE_1 = 13,
CPU_FLAG_NESTED_TASK = 14,
CPU_FLAG_RESUME = 16,
CPU_FLAG_VIRTUAL_8086 = 17,
CPU_FLAG_ALIGNMENT_CHECK = 18,
CPU_FLAG_VIRTUAL_INTERRUPT = 19,
CPU_FLAG_VIRTUAL_INTERRUPT_PENDING = 20,
CPU_FLAG_CPUID = 21
} cpu_flags_E;
typedef struct {
// Registers saved by assembly function
uint64_t cr3;
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
uint64_t rdi;
uint64_t rbp;
// Manually pushed
uint64_t interrupt_id;
uint64_t error_code;
// Saved by CPU
uint64_t rip;
uint64_t crs;
uint64_t flags;
uint64_t rsp;
uint64_t ss;
} cpu_state_T;
#endif //NOX_CPU_H

48
kernel/inc/platform/gdt.h Normal file
View File

@ -0,0 +1,48 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_GDT_H
#define NOX_GDT_H
#include "utils/stdtypes.h"
typedef struct {
uint16_t size;
uint64_t offset;
}__attribute__((packed)) gdt_descriptor_T;
typedef struct {
uint16_t limit0;
uint16_t base0;
uint8_t base1;
uint8_t access;
uint8_t limit1_flags;
uint8_t base2;
}__attribute__((packed)) gdt_entry_T;
typedef struct {
gdt_entry_T null; // 0x00
gdt_entry_T kernel_code; // 0x08
gdt_entry_T kernel_data; // 0x10
gdt_entry_T user_null; // 0x18
gdt_entry_T user_code; // 0x20
gdt_entry_T user_data; // 0x28
}__attribute__((packed)) __attribute__((aligned(0x1000))) gdt_T;
extern gdt_T g_default_gdt;
void gdt_init();
#endif //NOX_GDT_H

View File

@ -0,0 +1,42 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_INTERRUPTS_H
#define NOX_INTERRUPTS_H
#include "utils/stdtypes.h"
#define IDT_ENTRY_INTR_GATE 0b10001110
#define IDT_ENTRY_CALL_GATE 0b10001100
#define IDT_ENTRY_TRAP_GATE 0b10001111
typedef struct {
uint16_t limit;
uint64_t offset;
} __attribute__((packed)) idt_register_T;
typedef struct {
uint16_t offset0;
uint16_t selector;
uint8_t ist;
uint8_t type_attribute;
uint16_t offset1;
uint32_t offset2;
uint32_t ignore;
} idt_descriptor_entry_T;
void idt_init();
#endif //NOX_INTERRUPTS_H

32
kernel/inc/utils/bitmap.h Normal file
View File

@ -0,0 +1,32 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_BITMAP_H
#define NOX_BITMAP_H
#include "stdtypes.h"
typedef struct {
uint32_t size;
uint8_t* buffer;
} bitmap_T;
bitmap_T bitmap_init_from_buffer (void* buffer, uint32_t size);
bitmap_T bitmap_init (uint32_t size);
void bitmap_destruct (bitmap_T* bitmap);
bool bitmap_set (bitmap_T* bitmap, uint32_t index, bool value);
bool bitmap_get (bitmap_T* bitmap, uint32_t index);
#endif //NOX_BITMAP_H

22
kernel/inc/utils/core.h Normal file
View File

@ -0,0 +1,22 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NOX_CORE_H
#define NOX_CORE_H
#define CORE_HALT_FOREVER while(1) { asm("hlt"); }
#define CORE_HALT_WHILE(a) while(a) { asm("hlt"); }
#endif //NOX_CORE_H

View File

@ -16,7 +16,13 @@
#ifndef NOX_MATH_H #ifndef NOX_MATH_H
#define NOX_MATH_H #define NOX_MATH_H
#define max(a, b) (a > b ? a : b) #include "stdtypes.h"
#define min(a, b) (a > b ? b : a)
#define MAX(a, b) (a > b ? a : b)
#define MIN(a, b) (a > b ? b : a)
#define CEIL_TO(a, b) (a + b - (a % b))
#define FLOOR_TO(a, b) (a - (a % b))
uint64_t pow(uint64_t base, uint64_t exp);
#endif //NOX_MATH_H #endif //NOX_MATH_H

View File

@ -44,20 +44,19 @@ void _start() {
halt(); halt();
} }
log(LOG_INFO, "( LimineEntry ) Found Terminal"); log(LOG_INFO, "( LimineEntry ) Found Terminal");
boot_info.terminal = terminal_request.response->terminals[0]; boot_info.terminal = terminal_request.response;
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 0) { if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 0) {
halt(); halt();
} }
log(LOG_INFO, "( LimineEntry ) Found Framebuffer"); log(LOG_INFO, "( LimineEntry ) Found Framebuffer");
boot_info.framebuffer = framebuffer_request.response->framebuffers[0]; boot_info.framebuffer = framebuffer_request.response;
if (memmap_request.response == NULL || memmap_request.response->entry_count < 0) { if (memmap_request.response == NULL || memmap_request.response->entry_count < 0) {
halt(); halt();
} }
log(LOG_INFO, "( LimineEntry ) Found Memory Map"); log(LOG_INFO, "( LimineEntry ) Found Memory Map");
boot_info.memory_map_size = memmap_request.response->entry_count; boot_info.memory_map = memmap_request.response;
boot_info.memory_map = memmap_request.response->entries;
kmain(boot_info); kmain(boot_info);
} }

View File

@ -13,14 +13,32 @@
* If not, see <https://www.gnu.org/licenses/>. * If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "utils/stdtypes.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/core.h"
#include "boot/boot_info.h" #include "boot/boot_info.h"
#include "platform/gdt.h"
#include "platform/interrupts.h"
#include "mm/page_frame.h"
void limine_terminal_print(boot_info_T* boot_info, string_t string) {
boot_info->terminal->write(boot_info->terminal->terminals[0], string, string_length(string));
}
void kernel_init(boot_info_T* boot_info) {
gdt_init();
pframe_manager_init(boot_info);
idt_init();
}
void kmain(boot_info_T boot_info) { void kmain(boot_info_T boot_info) {
// terminal_request.response->write(terminal, "Booting NoxOS...", 16); limine_terminal_print(&boot_info, "Booting NoxOS...");
log(LOG_DEBUG, "Booting NoxOS"); log(LOG_DEBUG, "Booting NoxOS");
while(true) asm("hlt"); kernel_init(&boot_info);
log(LOG_DEBUG, "FIRING TEST INTERRUPT");
asm("int $0x01");
CORE_HALT_FOREVER
} }

View File

@ -0,0 +1,32 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "mm/memory_map.h"
#include "utils/logger.h"
uint64_t memory_map_get_total_memory_size(boot_info_T* boot_info) {
static uint64_t size = 0;
if (size > 0) {
log(LOG_INFO, "Memory size is already calculated, returning known value");
return size;
};
for (int i = 0; i < boot_info->memory_map->entry_count; i++) {
struct limine_memmap_entry* entry = boot_info->memory_map->entries[i];
size += entry->length;
}
return size;
}

187
kernel/src/mm/page_frame.c Normal file
View File

@ -0,0 +1,187 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "mm/page_frame.h"
#include "mm/memory_map.h"
#include "utils/logger.h"
#include "utils/math.h"
#include "utils/core.h"
page_frame_manager_T g_page_frame_manager;
void pframe_reserve(void* address) {
CORE_HALT_WHILE(g_page_frame_manager.blocked)
g_page_frame_manager.blocked = true;
uint64_t index = (uint64_t)address / PFRAME_SIZE;
if (bitmap_get(&g_page_frame_manager.page_bitmap, index)) {
g_page_frame_manager.blocked = false;
return;
}
if (bitmap_set(&g_page_frame_manager.page_bitmap, index, true)) {
g_page_frame_manager.free_memory -= PFRAME_SIZE;
g_page_frame_manager.reserved_memory += PFRAME_SIZE;
}
g_page_frame_manager.blocked = false;
}
void pframe_reserve_multi(void* address, uint32_t n) {
for (uint32_t i = 0; i < n; i++) {
pframe_reserve(&address[i * PFRAME_SIZE]);
}
}
void pframe_unreserve(void* address) {
CORE_HALT_WHILE(g_page_frame_manager.blocked)
g_page_frame_manager.blocked = true;
uint64_t index = (uint64_t)address / PFRAME_SIZE;
if (!bitmap_get(&g_page_frame_manager.page_bitmap, index)) {
g_page_frame_manager.blocked = false;
return;
}
if (bitmap_set(&g_page_frame_manager.page_bitmap, index, false)) {
g_page_frame_manager.free_memory += PFRAME_SIZE;
g_page_frame_manager.reserved_memory -= PFRAME_SIZE;
if (g_page_frame_manager.page_bitmap_index > index) {
g_page_frame_manager.page_bitmap_index = index;
}
}
g_page_frame_manager.blocked = false;
}
void pframe_unreserve_multi(void* address, uint32_t n) {
for (uint32_t i = 0; i < n; i++) {
pframe_unreserve(&address[i * PFRAME_SIZE]);
}
}
// this function should only be used by functions, that blocks the pframe manager
void pframe_lock(void* address) {
uint64_t index = (uint64_t)address / PFRAME_SIZE;
if (bitmap_get(&g_page_frame_manager.page_bitmap, index)) {
return;
}
if (bitmap_set(&g_page_frame_manager.page_bitmap, index, true)) {
g_page_frame_manager.free_memory -= PFRAME_SIZE;
g_page_frame_manager.used_memory += PFRAME_SIZE;
}
}
void pframe_lock_multi(void* address, uint32_t n) {
for (uint32_t i = 0; i < n; i++) {
pframe_lock(&address[i * PFRAME_SIZE]);
}
}
void pframe_free(void* address) {
CORE_HALT_WHILE(g_page_frame_manager.blocked)
g_page_frame_manager.blocked = true;
uint64_t index = (uint64_t)address / PFRAME_SIZE;
if (!bitmap_get(&g_page_frame_manager.page_bitmap, index)) {
g_page_frame_manager.blocked = false;
return;
}
if (bitmap_set(&g_page_frame_manager.page_bitmap, index, false)) {
g_page_frame_manager.free_memory += PFRAME_SIZE;
g_page_frame_manager.used_memory -= PFRAME_SIZE;
if (g_page_frame_manager.page_bitmap_index > index) {
g_page_frame_manager.page_bitmap_index = index;
}
}
g_page_frame_manager.blocked = false;
}
void pframe_free_multi(void* address, uint32_t n) {
for (uint32_t i = 0; i < n; i++) {
pframe_free(&address[i * PFRAME_SIZE]);
}
}
void* pframe_request() {
CORE_HALT_WHILE(g_page_frame_manager.blocked)
g_page_frame_manager.blocked = true;
while (g_page_frame_manager.page_bitmap_index < g_page_frame_manager.page_bitmap.size * 8) {
if (bitmap_get(&g_page_frame_manager.page_bitmap, g_page_frame_manager.page_bitmap_index)) {
g_page_frame_manager.page_bitmap_index++;
continue;
}
void* address = (void*)(g_page_frame_manager.page_bitmap_index * PFRAME_SIZE);
pframe_lock(address);
g_page_frame_manager.blocked = false;
return address;
}
g_page_frame_manager.blocked = false;
return NULL;
}
void pframe_manager_init(boot_info_T* boot_info) {
log(LOG_INFO, "<PageFrameManager> Initializing");
struct limine_memmap_entry* largest_usable_entry = NULL;
for (int i = 0; i < boot_info->memory_map->entry_count; i++) {
struct limine_memmap_entry* entry = boot_info->memory_map->entries[i];
if (entry->type != LIMINE_MEMMAP_USABLE) { continue; }
if (largest_usable_entry != NULL && largest_usable_entry->length > entry->length) { continue; }
largest_usable_entry = entry;
}
uint64_t total_memory = memory_map_get_total_memory_size(boot_info);
log(LOG_INFO, " * Total Memory size: 'size'"); // TODO: replace with format string
g_page_frame_manager.page_bitmap = bitmap_init_from_buffer((void*)largest_usable_entry->base, total_memory / PFRAME_SIZE / 8 + 1);
g_page_frame_manager.page_bitmap_index = 0;
g_page_frame_manager.reserved_memory = 0;
g_page_frame_manager.used_memory = 0;
g_page_frame_manager.free_memory = total_memory;
pframe_reserve_multi(0, total_memory / PFRAME_SIZE + 1);
log(LOG_INFO, " * Reserved all pages");
for (int i = 0; i < boot_info->memory_map->entry_count; i++) {
struct limine_memmap_entry* entry = boot_info->memory_map->entries[i];
if (entry->type != LIMINE_MEMMAP_USABLE) { continue; }
pframe_unreserve_multi((void*)entry->base, entry->length / PFRAME_SIZE);
}
log(LOG_INFO, " * Unreserved usable pages");
pframe_lock_multi(g_page_frame_manager.page_bitmap.buffer, g_page_frame_manager.page_bitmap.size / PFRAME_SIZE);
log(LOG_INFO, " * Locked page_bitmap pages");
log(LOG_INFO, " * Finished initialization");
g_page_frame_manager.blocked = false;
}

39
kernel/src/platform/gdt.c Normal file
View File

@ -0,0 +1,39 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "platform/gdt.h"
#include "utils/logger.h"
extern void gdt_load(gdt_descriptor_T* gdt_descriptor);
__attribute__((aligned(0x1000)))
gdt_T g_default_gdt = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x9A, 0xA0, 0x00},
{0x00, 0x00, 0x00, 0x92, 0xA0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x9A, 0xA0, 0x00},
{0x00, 0x00, 0x00, 0x92, 0xA0, 0x00}
};
void gdt_init() {
gdt_descriptor_T descriptor;
descriptor.size = sizeof(gdt_T) - 1;
descriptor.offset = (uint64_t)&g_default_gdt;
gdt_load(&descriptor);
log(LOG_INFO, "GDT loaded");
}

View File

@ -0,0 +1,124 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "platform/interrupts.h"
#include "platform/cpu.h"
#include "mm/page_frame.h"
#include "utils/logger.h"
idt_register_T g_idt_register;
extern void idt_load(idt_register_T* idt_register);
extern void interrupt_stub_0x00();
extern void interrupt_stub_0x01();
extern void interrupt_stub_0x02();
extern void interrupt_stub_0x03();
extern void interrupt_stub_0x04();
extern void interrupt_stub_0x05();
extern void interrupt_stub_0x06();
extern void interrupt_stub_0x07();
extern void interrupt_stub_0x08();
extern void interrupt_stub_0x09();
extern void interrupt_stub_0x0A();
extern void interrupt_stub_0x0B();
extern void interrupt_stub_0x0C();
extern void interrupt_stub_0x0D();
extern void interrupt_stub_0x0E();
extern void interrupt_stub_0x0F();
extern void interrupt_stub_0x10();
extern void interrupt_stub_0x11();
extern void interrupt_stub_0x12();
extern void interrupt_stub_0x13();
extern void interrupt_stub_0x14();
extern void interrupt_stub_0x15();
extern void interrupt_stub_0x16();
extern void interrupt_stub_0x17();
extern void interrupt_stub_0x18();
extern void interrupt_stub_0x19();
extern void interrupt_stub_0x1A();
extern void interrupt_stub_0x1B();
extern void interrupt_stub_0x1C();
extern void interrupt_stub_0x1D();
extern void interrupt_stub_0x1E();
extern void interrupt_stub_0x1F();
void idt_set_descriptor_entry_offset(idt_descriptor_entry_T* entry, uint64_t offset) {
entry->offset0 = (uint16_t) (offset & 0x000000000000ffff);
entry->offset1 = (uint16_t) ((offset & 0x00000000ffff0000) >> 16);
entry->offset2 = (uint32_t) ((offset & 0xffffffff00000000) >> 32);
}
uint64_t idt_get_descriptor_entry_offset(idt_descriptor_entry_T* entry) {
uint64_t offset = 0;
offset |= (uint64_t)entry->offset0;
offset |= (uint64_t)entry->offset1 << 16;
offset |= (uint64_t)entry->offset2 << 32;
return offset;
}
void idt_set_gate(void* handler, uint8_t entry_offset, uint8_t type_attribute, uint8_t selector) {
idt_descriptor_entry_T* entry = (idt_descriptor_entry_T*)(g_idt_register.offset + entry_offset * sizeof(idt_descriptor_entry_T));
idt_set_descriptor_entry_offset(entry, (uint64_t)handler);
entry->type_attribute = type_attribute;
entry->selector = selector;
}
void idt_init() {
g_idt_register.limit = 0x0FFF;
g_idt_register.offset = (uint64_t)pframe_request();
idt_set_gate((void*)interrupt_stub_0x00, 0x00, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x01, 0x01, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x02, 0x02, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x03, 0x03, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x04, 0x04, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x05, 0x05, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x06, 0x06, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x07, 0x07, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x08, 0x08, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x09, 0x09, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x0A, 0x0A, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x0B, 0x0B, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x0C, 0x0C, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x0D, 0x0D, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x0E, 0x0E, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x0F, 0x0F, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x10, 0x10, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x11, 0x11, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x12, 0x12, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x13, 0x13, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x14, 0x14, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x15, 0x15, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x16, 0x16, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x17, 0x17, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x18, 0x18, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x19, 0x19, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x1A, 0x1A, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x1B, 0x1B, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x1C, 0x1C, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x1D, 0x1D, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x1E, 0x1E, IDT_ENTRY_INTR_GATE, 0x08);
idt_set_gate((void*)interrupt_stub_0x1F, 0x1F, IDT_ENTRY_INTR_GATE, 0x08);
idt_load(&g_idt_register);
log(LOG_INFO, "Interrupts initialized");
}
cpu_state_T* interrupts_handle(cpu_state_T* state) {
log(LOG_DEBUG, "Interrupt");
while(true)asm("hlt");
}

View File

@ -0,0 +1,4 @@
gdt_load:
lgdt [rax]
ret
GLOBAL gdt_load

View File

@ -0,0 +1,93 @@
extern interrupts_handle
idt_load:
lidt [rax]
ret
GLOBAL idt_load
interrupt_common_handler:
; save CPU state
push rbp
push rdi
push rsi
push rdx
push rcx
push rbx
push rax
; save page map
mov rax, cr3
push rax
; call handler
mov rdi, rsp
call interrupts_handle
mov rsp, rax
; load cpu_state
pop rax
mov cr3, rax
; restore CPU state
pop rax
pop rbx
pop rcx
pop rdx
pop rsi
pop rdi
pop rbp
; remove error_code and interrupt number from stack
add rsp, 16
iretq
GLOBAL interrupt_common_handler
%macro interrupt_stub 1
interrupt_stub_%1:
push qword 0
push qword %1
jmp interrupt_common_handler
GLOBAL interrupt_stub_%1
%endmacro
%macro interrupt_stub_error_code 1
interrupt_stub_%1:
push qword %1
jmp interrupt_common_handler
GLOBAL interrupt_stub_%1
%endmacro
; Exceptions
interrupt_stub 0x00
interrupt_stub 0x01
interrupt_stub 0x02
interrupt_stub 0x03
interrupt_stub 0x04
interrupt_stub 0x05
interrupt_stub 0x06
interrupt_stub 0x07
interrupt_stub_error_code 0x08
interrupt_stub 0x09
interrupt_stub_error_code 0x0A
interrupt_stub_error_code 0x0B
interrupt_stub_error_code 0x0C
interrupt_stub_error_code 0x0D
interrupt_stub_error_code 0x0E
interrupt_stub 0x0F
interrupt_stub 0x10
interrupt_stub_error_code 0x11
interrupt_stub 0x12
interrupt_stub 0x13
interrupt_stub 0x14
interrupt_stub 0x15
interrupt_stub 0x16
interrupt_stub 0x17
interrupt_stub 0x18
interrupt_stub 0x19
interrupt_stub 0x1A
interrupt_stub 0x1B
interrupt_stub 0x1C
interrupt_stub 0x1D
interrupt_stub 0x1E
interrupt_stub 0x1F

View File

@ -1,5 +0,0 @@
lol:
hlt
jmp lol
GLOBAL lol

55
kernel/src/utils/bitmap.c Normal file
View File

@ -0,0 +1,55 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "utils/bitmap.h"
bitmap_T bitmap_init_from_buffer(void* buffer, uint32_t size) {
bitmap_T bitmap;
bitmap.buffer = buffer;
bitmap.size = size;
return bitmap;
}
bitmap_T bitmap_init(uint32_t size) {
// TODO: implement bitmap malloc constructor
}
void bitmap_destruct(bitmap_T* bitmap) {
}
bool bitmap_set(bitmap_T* bitmap, uint32_t index, bool value) {
if (index >= bitmap->size) { return false; }
uint32_t index_byte = index / 8;
uint8_t index_bit = index % 8;
bitmap->buffer[index_byte] &= ~(0b10000000 >> index_bit);
if (value) {
bitmap->buffer[index_byte] |= (0b10000000 >> index_bit);
}
return true;
}
bool bitmap_get(bitmap_T* bitmap, uint32_t index) {
if (index >= bitmap->size) { return false; }
uint32_t index_byte = index / 8;
uint8_t index_bit = index % 8;
return (bitmap->buffer[index_byte] & (0b10000000 >> index_bit)) > 0;
}

24
kernel/src/utils/math.c Normal file
View File

@ -0,0 +1,24 @@
/* Copyright (C) Antifallobst <antifallobst@systemausfall.org>
*
* NoxOS is free software:
* you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* NoxOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "utils/math.h"
uint64_t pow(uint64_t base, uint64_t exp) {
uint64_t n = 1;
for (uint64_t i = 0; i < exp; i++) {
n *= base;
}
return n;
}

View File

@ -1,4 +1,4 @@
TIMEOUT=5 TIMEOUT=2
:NoxOS :NoxOS
PROTOCOL=limine PROTOCOL=limine

14
run.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
EMUFLAGS="-no-reboot -m 256M -cdrom build/noxos.iso -chardev stdio,id=log,logfile=noxos.log -serial chardev:log"
emulate() {
qemu-system-x86_64 $EMUFLAGS
}
# qemu will wait for gdb to connect, before booting
emulate_debug() {
qemu-system-x86_64 -s -S $EMUFLAGS
}
emulate_debug