diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..70e34ec --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.errorSquiggles": "disabled" +} \ No newline at end of file diff --git a/README.md b/README.md index 2d82302..bfbb91c 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# MSEOS: минимальная студенческая обучающая операционная система +# БМПОС: Базовая Модульная Платформа Операционных Систем -[![CI BUILD](https://github.com/0Nera/MSEOS/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/0Nera/MSEOS/actions/workflows/build.yml) -[![Github pages](https://github.com/0Nera/MSEOS/actions/workflows/pages/pages-build-deployment/badge.svg?branch=pages)](https://github.com/0Nera/MSEOS/actions/workflows/pages/pages-build-deployment) +[![CI сборка](https://github.com/0Nera/BMOSP/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/0Nera/MSEOS/actions/workflows/build.yml) +[![Github pages сайт](https://github.com/0Nera/BMOSP/actions/workflows/pages/pages-build-deployment/badge.svg?branch=pages)](https://github.com/0Nera/MSEOS/actions/workflows/pages/pages-build-deployment) -MSEOS - минимальная студенческая обучающая операционная система с открытым исходным кодом для платформы x86_64(BIOS/UEFI). Это отечественная операционная система. +БМПОС - Базовая Модульная Платформа Операционных Систем для платформы x86_64 (BIOS/UEFI). Это отечественное программное обеспечение, созданное при поддержке Синапс ОС на языке программирования C++. Система: - [ ] Менеджер памяти @@ -41,11 +41,20 @@ MSEOS - минимальная студенческая обучающая оп - Страница вконтакте - Вебсайт -- Страница на вики +- Страница на вики ### Зеркала -- - доверенный сервер(главный репозиторий) -- - зеркало -- - зеркало -- - неактивное зеркало +- - доверенный сервер(главный репозиторий) +- - зеркало +- - зеркало +- - неактивное зеркало + +### Использованные ресурсы + +- https://github.com/limine-bootloader/limine (BSD 2-Clause) +- https://github.com/nothings/stb (MIT, Общественное достояние) +- https://en.wikipedia.org/wiki/CPUID +- https://github.com/klange/toaruos (NCSA) +- https://wiki.osdev.org/Model_Specific_Registers +- https://sandpile.org/x86/msr.htm \ No newline at end of file diff --git a/build.py b/build.py index 64f6dbe..2026728 100644 --- a/build.py +++ b/build.py @@ -5,14 +5,46 @@ import time from multiprocessing import Pool -CC = "g++" -ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-80387 -mno-red-zone -mcmodel=kernel -MMD -MP" -WARN_FLAGS = "-w -Wall -Wextra" +ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-red-zone -mcmodel=kernel -MMD -MP" +WARN_FLAGS = "-w -Wall -Wextra -nostdlib" STANDART_FLAGS = "-std=gnu11" PROTECT_FLAGS = "-O0 -pipe -ffreestanding -fno-stack-protector -fno-lto -fno-stack-check -fno-PIC -fno-PIE" CHARSET_FLAGS = "-finput-charset=UTF-8 -fexec-charset=cp1251" LIBS_FLAGS = "-Ilimine -Iinclude" +def version_build(): + with open("include/version.h", "r") as file: + lines = file.readlines() + + major = 0 + minor = 0 + build = 0 + + with open("include/version.h", "w") as file: + for line in lines: + if line.startswith("#define VERSION_BUILD"): + parts = line.split() + build = int(parts[2]) + 1 + if build > 255: + build = 0 + minor += 1 + file.write(f"#define VERSION_MINOR {minor}\n") + file.write(f"#define VERSION_BUILD {build}\n") + elif line.startswith("#define VERSION_MAJOR"): + parts = line.split() + major = int(parts[2]) + file.write(line) + elif line.startswith("#define VERSION_MINOR"): + parts = line.split() + minor = int(parts[2]) + file.write(line) + else: + file.write(line) + + return [major, minor, build] + +def sort_strings(strings): + return sorted(strings, key=lambda x: not x.endswith('.s.o')) def find_files(directory, extensions): file_list = [] @@ -24,6 +56,7 @@ def find_files(directory, extensions): def compile(file: str): + CC = "g++" if file.endswith('cpp') else "gcc" output_file = file.replace('/', '_') obj_file = f"bin/{output_file}.o" cmd = f"{CC} {WARN_FLAGS} {PROTECT_FLAGS} {ARCH_FLAGS} {CHARSET_FLAGS} {LIBS_FLAGS} -c {file} -o {obj_file}" @@ -33,7 +66,8 @@ def compile(file: str): def compile_all(): - file_list = find_files("kernel/", [".c", ".cpp", ".s"]) + file_list = find_files("kernel/", [".s", ".cpp", ".c"]) + file_list += find_files("kernel/*/*", [".s", ".cpp", ".c"]) with Pool() as pool: results = pool.map(compile, file_list) @@ -42,7 +76,7 @@ def compile_all(): print(results) time.sleep(1) print(results) - cmd = f"ld -nostdlib -static -m elf_x86_64 -z max-page-size=0x1000 -T configs/linker.ld -o kernel.elf {' '.join(results)}" + cmd = f"ld -nostdlib -static -m elf_x86_64 -z max-page-size=0x1000 -T configs/linker.ld -o kernel.elf {' '.join(sort_strings(results))}" print(cmd) os.system(cmd) @@ -77,13 +111,16 @@ def create_hdd(IMAGE_NAME): subprocess.run(["sgdisk", IMAGE_NAME+".hdd", "-n", "1:2048", "-t", "1:ef00"]) subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".hdd"]) subprocess.run(["mformat", "-i", IMAGE_NAME+".hdd@@1M"]) - subprocess.run(["mmd", "-i", IMAGE_NAME+".hdd@@1M", "::/mod", "::/EFI", "::/EFI/BOOT"]) + subprocess.run(["mmd", "-i", IMAGE_NAME+".hdd@@1M", "::/mod", "::/EFI", "::/EFI/BOOT", "::/user"]) subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", "kernel.elf", "configs/limine.cfg", "limine/limine-bios.sys", "::/"]) subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", "modules/com/com.elf", "modules/helloworld/helloworld.elf", "::/mod"]) subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", "limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"]) + subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", + "boot.png", "::/"]) + subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".hdd"]) def create_iso(IMAGE_NAME): @@ -91,12 +128,12 @@ def create_iso(IMAGE_NAME): subprocess.run(["rm", "-rf", "iso_root"]) subprocess.run(["mkdir", "-p", "iso_root"]) subprocess.run(["cp", "-v", "iso_root/"]) - subprocess.run(["cp", "-v", "kernel.elf", + subprocess.run(["cp", "-v", "kernel.elf", "boot.png", "configs/limine.cfg", "limine/limine-bios.sys", "limine/limine-bios-cd.bin", "limine/limine-uefi-cd.bin", "iso_root/"]) subprocess.run(["mkdir", "-p", "iso_root/EFI/BOOT"]) - subprocess.run(["mkdir", "-p", "iso_root/mod/"]) + subprocess.run(["mkdir", "-p", "iso_root/mod"]) subprocess.run(["cp", "-v", "modules/helloworld/helloworld.elf", "iso_root/mod/"]) subprocess.run(["cp", "-v", "modules/com/com.elf", "iso_root/mod/"]) subprocess.run(["cp", "-v", "limine/BOOTX64.EFI", "iso_root/EFI/BOOT/"]) @@ -107,7 +144,6 @@ def create_iso(IMAGE_NAME): "-efi-boot-part", "--efi-boot-image", "--protective-msdos-label", "iso_root", "-o", IMAGE_NAME+".iso"]) subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".iso"]) - subprocess.run(["rm", "-rf", "iso_root"]) if __name__ == "__main__": os.system("""find . \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) -print0 | xargs -0 clang-format -i -style=file""") @@ -123,7 +159,8 @@ if __name__ == "__main__": check_limine() check_tools() compile_all() - create_iso("mseos") - create_hdd("mseos") + create_iso("bmosp") + create_hdd("bmosp") - print("qemu-system-x86_64 -M q35 -m 8G -smp 8 -bios ovmf/OVMF.fd -hda mseos.hdd") \ No newline at end of file + major, minor, build = version_build() + print(f"Не забудьте сохранить изменения! Номер сборки: {major}.{minor}, {build}") \ No newline at end of file diff --git a/configs/limine.cfg b/configs/limine.cfg index c905664..ac1fec1 100644 --- a/configs/limine.cfg +++ b/configs/limine.cfg @@ -1,20 +1,23 @@ +GRAPHICS=yes TIMEOUT=5 DEFAULT_ENTRY=0 INTERFACE_BRANDING=By Aren Elchinyan - +BACKGROUND_STYLE=stretched +BACKGROUND_PATH=boot:///boot.png #TERM_FONT=boot:///CYRILL2.F16 #TERM_FONT_SIZE=8x16 -:MSEOS (KASLR on) +:BMOSP (KASLR on) + #RESOLUTION=1280x720 PROTOCOL=limine KASLR=no KERNEL_PATH=boot:///kernel.elf - MODULE_PATH=boot:///kernel.elf - MODULE_CMDLINE=boot:///kernel.elf - MODULE_PATH=boot:///mod/helloworld.elf MODULE_CMDLINE=helloworld MODULE_PATH=boot:///mod/com.elf - MODULE_CMDLINE=com \ No newline at end of file + MODULE_CMDLINE=com + + MODULE_PATH=boot:///boot.png + MODULE_CMDLINE=bootimage \ No newline at end of file diff --git a/deploy_to_sdc.sh b/deploy_to_sdc.sh new file mode 100644 index 0000000..80a690f --- /dev/null +++ b/deploy_to_sdc.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sudo dd if=mseos.hdd of=/dev/sdc \ No newline at end of file diff --git a/include/version.h b/include/version.h new file mode 100644 index 0000000..ff6a4b1 --- /dev/null +++ b/include/version.h @@ -0,0 +1,3 @@ +#define VERSION_MAJOR 0 +#define VERSION_MINOR 1 +#define VERSION_BUILD 2 diff --git a/kernel/arch.cpp b/kernel/arch/arch.cpp similarity index 78% rename from kernel/arch.cpp rename to kernel/arch/arch.cpp index f9850fe..7bb93c1 100644 --- a/kernel/arch.cpp +++ b/kernel/arch/arch.cpp @@ -1,15 +1,23 @@ -#include - -namespace arch { -static volatile struct limine_kernel_address_request kernel_address_request = { - .id = LIMINE_KERNEL_ADDRESS_REQUEST, - .revision = 0, - .response = (struct limine_kernel_address_response *)0 -}; - -struct limine_kernel_address_response *kernel_address_response; - -void init( ) { - kernel_address_response = kernel_address_request.response; -} +#include + +extern "C" { +void gdt_init( ); + +void idt_init( ); +} + +namespace arch { +static volatile struct limine_kernel_address_request kernel_address_request = { + .id = LIMINE_KERNEL_ADDRESS_REQUEST, + .revision = 0, + .response = (struct limine_kernel_address_response *)0 +}; + +struct limine_kernel_address_response *kernel_address_response; + +void init( ) { + kernel_address_response = kernel_address_request.response; + gdt_init( ); + idt_init( ); +} } // namespace arch \ No newline at end of file diff --git a/kernel/cpu.cpp b/kernel/arch/cpu.cpp similarity index 92% rename from kernel/cpu.cpp rename to kernel/arch/cpu.cpp index e7c78e7..a99618c 100644 --- a/kernel/cpu.cpp +++ b/kernel/arch/cpu.cpp @@ -1,168 +1,170 @@ -#include -#include -#include -#include - -namespace cpu { -static bool acpi_msrs_support = false; -static bool mmx_support = false; -static bool sse2_support = false; -static bool avx_support = false; -static bool rdrnd_support = false; - -void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, - uint32_t *edx) { - asm volatile("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(leaf)); -} - -void msr_get(uint32_t msr, uint32_t *lo, uint32_t *hi) { - asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); -} - -void msr_set(uint32_t msr, uint32_t lo, uint32_t hi) { - asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); -} - -uint64_t get_cpu_temperature( ) { - uint32_t lo, hi; - - // Чтение температуры из MSR - cpu::msr_get(0x19C, &lo, &hi); - - uint64_t temp = ((uint64_t)hi << 32) | (uint64_t)lo; - - // Преобразование значения температуры - uint64_t temperature = (temp >> 16) / 256; - - return temperature; -} - -void l2_cache( ) { - unsigned int eax, ebx, ecx, edx; - unsigned int lsize, assoc, cache; - - cpuid(0x80000005, &eax, &ebx, &ecx, &edx); - lsize = ecx & 0xFF; - fb::printf("Кэш L1: %d KB\n", lsize); - - cpuid(0x80000006, &eax, &ebx, &ecx, &edx); - lsize = ecx & 0xFF; - assoc = (ecx >> 12) & 0x0F; - cache = (ecx >> 16) & 0xFF; - - fb::printf("Кэш L2: %d KB\n", lsize); -} - -void do_amd( ) { - uint32_t eax, ebx, ecx, edx; - uint32_t eggs[4]; - uint32_t cpu_model; - uint32_t cpu_family; - char eggs_string[13]; - - cpuid(0x8FFFFFFF, &eggs[0], &eggs[1], &eggs[2], &eggs[3]); - tool::memcpy(eggs_string, eggs, 12); - - cpuid(1, &eax, &ebx, &ecx, &edx); - cpu_model = (eax >> 4) & 0x0F; - cpu_family = (eax >> 8) & 0x0F; - - fb::printf("Используется процессор AMD, 8FFFFFFF = [%s]\n", eggs_string); - fb::printf("cpu_model = [%u]\n", cpu_model); - fb::printf("cpu_family = [%u]\n", cpu_family); -} - -void brandname( ) { - uint32_t eax, ebx, ecx, edx; - char brand_string[49]; - uint32_t brand[12]; - uint32_t manufacturer[4]; - char manufacturer_string[13]; - - cpuid(0, &manufacturer[3], &manufacturer[0], &manufacturer[2], - &manufacturer[1]); - tool::memcpy(manufacturer_string, manufacturer, 12); - - brand_string[48] = 0; - manufacturer_string[12] = 0; - - fb::printf("[CPUID] manufacturer [%s]\n", manufacturer_string); - - cpuid(0x80000000, &eax, &ebx, &ecx, &edx); - if (eax >= 0x80000004) { - cpuid(0x80000002, &brand[0], &brand[1], &brand[2], &brand[3]); - cpuid(0x80000003, &brand[4], &brand[5], &brand[6], &brand[7]); - cpuid(0x80000004, &brand[8], &brand[9], &brand[10], &brand[11]); - tool::memcpy(brand_string, brand, 48); - fb::printf("[CPUID] 0x80000002:0x80000004 [%s]\n", brand_string); - } - - if (manufacturer[0] == 0x68747541) { do_amd( ); } -} - -void sse_init( ) { - asm volatile("clts\n" - "mov %%cr0, %%rax\n" - "and $0xFFFD, %%ax\n" - "or $0x10, %%ax\n" - "mov %%rax, %%cr0\n" - "fninit\n" - "mov %%cr0, %%rax\n" - "and $0xfffb, %%ax\n" - "or $0x0002, %%ax\n" - "mov %%rax, %%cr0\n" - "mov %%cr4, %%rax\n" - "or $0x600, %%rax\n" - "mov %%rax, %%cr4\n" - "push $0x1F80\n" - "ldmxcsr (%%rsp)\n" - "addq $8, %%rsp\n" - : - : - : "rax"); -} - -void init( ) { - uint32_t eax, ebx, ecx, edx; - cpuid(1, &eax, &ebx, &ecx, &edx); - - if ((edx >> 0) & 1) { fb::printf("FPU(x87) подерживается!\n"); } - - if ((edx >> 22) & 1) { - acpi_msrs_support = true; - fb::printf("Встроенный терморегулятор MSRS для ACPI\n"); - fb::printf("Температура: %u\n", get_cpu_temperature( )); - } - - if ((edx >> 23) & 1) { - mmx_support = true; - fb::printf("MMX подерживается!\n"); - } - - if ((edx >> 25) & 1) { - sse2_support = true; - fb::printf("SSE2 подерживается!\n"); - sse_init( ); - } - - if ((edx >> 29) & 1) { - fb::printf("Термоконтроллер автоматически ограничивает температуру\n"); - } - - if ((ecx >> 28) & 1) { - avx_support = true; - fb::printf("AVX подерживается!\n"); - } - - cpuid(0x7, &eax, &ebx, &ecx, &edx); - if ((ebx >> 30) & 1) { - rdrnd_support = true; - fb::printf("RDRND подерживается!\n"); - } - - brandname( ); - l2_cache( ); -} +#include +#include +#include +#include + +namespace cpu { +static bool acpi_msrs_support = false; +static bool mmx_support = false; +static bool sse2_support = false; +static bool avx_support = false; +static bool rdrnd_support = false; + +void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, + uint32_t *edx) { + asm volatile("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(leaf)); +} + +void msr_get(uint32_t msr, uint32_t *lo, uint32_t *hi) { + asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); +} + +void msr_set(uint32_t msr, uint32_t lo, uint32_t hi) { + asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); +} + +uint64_t get_cpu_temperature( ) { + uint32_t lo, hi; + + // Чтение температуры из MSR + cpu::msr_get(0x19C, &lo, &hi); + + uint64_t temp = ((uint64_t)hi << 32) | (uint64_t)lo; + + // Преобразование значения температуры + uint64_t temperature = (temp >> 16) / 256; + + return temperature; +} + +void l2_cache( ) { + unsigned int eax, ebx, ecx, edx; + unsigned int lsize, assoc, cache; + + cpuid(0x80000005, &eax, &ebx, &ecx, &edx); + lsize = ecx & 0xFF; + fb::printf("Кэш L1: %d KB\n", lsize); + + cpuid(0x80000006, &eax, &ebx, &ecx, &edx); + lsize = ecx & 0xFF; + assoc = (ecx >> 12) & 0x0F; + cache = (ecx >> 16) & 0xFF; + + fb::printf("Кэш L2: %d KB\n", lsize); +} + +void do_amd( ) { + uint32_t eax, ebx, ecx, edx; + uint32_t eggs[4]; + uint32_t cpu_model; + uint32_t cpu_family; + char eggs_string[13]; + + cpuid(0x8FFFFFFF, &eggs[0], &eggs[1], &eggs[2], &eggs[3]); + tool::memcpy(eggs_string, eggs, 12); + + cpuid(1, &eax, &ebx, &ecx, &edx); + cpu_model = (eax >> 4) & 0x0F; + cpu_family = (eax >> 8) & 0x0F; + + fb::printf("Используется процессор AMD, 0x8FFFFFFF = [%s]\n", eggs_string); + fb::printf("cpu_model = [%u]\n", cpu_model); + fb::printf("cpu_family = [%u]\n", cpu_family); +} + +void brandname( ) { + uint32_t eax, ebx, ecx, edx; + char brand_string[49]; + uint32_t brand[12]; + uint32_t manufacturer[4]; + char manufacturer_string[13]; + + cpuid(0, &manufacturer[3], &manufacturer[0], &manufacturer[2], + &manufacturer[1]); + tool::memcpy(manufacturer_string, manufacturer, 12); + + brand_string[48] = 0; + manufacturer_string[12] = 0; + + fb::printf("[CPUID] manufacturer [%s]\n", manufacturer_string); + + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + if (eax >= 0x80000004) { + cpuid(0x80000002, &brand[0], &brand[1], &brand[2], &brand[3]); + cpuid(0x80000003, &brand[4], &brand[5], &brand[6], &brand[7]); + cpuid(0x80000004, &brand[8], &brand[9], &brand[10], &brand[11]); + tool::memcpy(brand_string, brand, 48); + fb::printf("[CPUID] 0x80000002:0x80000004 [%s]\n", brand_string); + } + + if (manufacturer[0] == 0x68747541) { do_amd( ); } +} + +void sse_init( ) { + asm volatile("clts\n" + "mov %%cr0, %%rax\n" + "and $0xFFFD, %%ax\n" + "or $0x10, %%ax\n" + "mov %%rax, %%cr0\n" + "fninit\n" + "mov %%cr0, %%rax\n" + "and $0xfffb, %%ax\n" + "or $0x0002, %%ax\n" + "mov %%rax, %%cr0\n" + "mov %%cr4, %%rax\n" + "or $0x600, %%rax\n" + "mov %%rax, %%cr4\n" + "push $0x1F80\n" + "ldmxcsr (%%rsp)\n" + "addq $8, %%rsp\n" + : + : + : "rax"); +} + +void init( ) { + uint32_t eax, ebx, ecx, edx; + cpuid(1, &eax, &ebx, &ecx, &edx); + + if ((edx >> 0) & 1) { fb::printf("FPU(x87) подерживается!\n"); } + + if ((edx >> 22) & 1) { + acpi_msrs_support = true; + fb::printf("Температура: %u\n", get_cpu_temperature( )); + fb::printf("Встроенный терморегулятор MSRS для ACPI\n"); + } + + if ((edx >> 23) & 1) { + mmx_support = true; + fb::printf("MMX подерживается!\n"); + } + + if ((edx >> 25) & 1) { + sse2_support = true; + fb::printf("SSE2 подерживается!\n"); + sse_init( ); + } + + cpuid(1, &eax, &ebx, &ecx, &edx); + if ((edx >> 29) & 1) { + fb::printf("Термоконтроллер автоматически ограничивает температуру\n"); + } + + if ((ecx >> 28) & 1) { + avx_support = true; + fb::printf("AVX подерживается!\n"); + } + + if ((ecx >> 26) & 1) { fb::printf("XSAVE подерживается!\n"); } + + if ((ecx >> 30) & 1) { + rdrnd_support = true; + fb::printf("RDRND подерживается!\n"); + } + + brandname( ); + l2_cache( ); +} } // namespace cpu \ No newline at end of file diff --git a/kernel/arch/gdt.cpp b/kernel/arch/gdt.cpp new file mode 100644 index 0000000..1de5a0f --- /dev/null +++ b/kernel/arch/gdt.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +extern "C" { + +typedef struct __attribute__((packed)) { + uint16_t limit; + uint16_t base_16; + uint8_t base_middle_16; + uint8_t access; + uint8_t granularity; + uint8_t base_hight_8; +} gdt_entry_t; + +typedef struct __attribute__((packed)) { + uint16_t limit; + uint64_t base; +} gdt_reg_t; + +gdt_entry_t gdt[11]; +gdt_reg_t gdtr; + +extern void load_gdt(uint64_t gdtr); + +void gdt_load( ) { + gdtr.limit = (sizeof(gdt) - 1); + gdtr.base = (uint64_t)&gdt; + + load_gdt((uint64_t)&gdtr); +} + +void set_gdt_entry(gdt_entry_t *entry, uint16_t limit, uint64_t base, + uint8_t access, uint8_t granularity) { + entry->limit = limit; + entry->base_16 = base & 0xFFFF; + entry->base_middle_16 = (base >> 16) & 0xFF; + entry->base_hight_8 = (base >> 24) & 0xFF; + entry->access = access; + entry->granularity = granularity; +} + +void gdt_init( ) { + set_gdt_entry(&gdt[0], 0, 0, 0, 0); + set_gdt_entry(&gdt[1], 0xFFFF, 0, 0x9A, 0); + set_gdt_entry(&gdt[2], 0xFFFF, 0, 0x92, 0); + set_gdt_entry(&gdt[3], 0xFFFF, 0, 0x9A, 0xCF); + set_gdt_entry(&gdt[4], 0xFFFF, 0, 0x92, 0xCF); + set_gdt_entry(&gdt[5], 0, 0, 0x9A, 0x20); + set_gdt_entry(&gdt[6], 0, 0, 0x92, 0); + set_gdt_entry(&gdt[7], 0, 0, 0xFA, 0x20); + set_gdt_entry(&gdt[8], 0, 0, 0xF2, 0); + set_gdt_entry(&gdt[9], 104, 0, 0x89, 0); + set_gdt_entry(&gdt[10], 0, 0, 0, 0); + + gdt_load( ); + fb::printf("GDT инициализирован\n"); +} +} diff --git a/kernel/arch/idt.cpp b/kernel/arch/idt.cpp new file mode 100644 index 0000000..594b09e --- /dev/null +++ b/kernel/arch/idt.cpp @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include + +extern "C" { +typedef struct __attribute__((packed)) { + uint16_t limit; + uint64_t base; +} idt_ptr_t; + +typedef struct __attribute__((packed)) { + uint16_t offset_16; + uint16_t selector; + uint8_t ist; + uint8_t flags; + uint16_t offset_middle_16; + uint32_t offset_high_32; + uint32_t reserved; +} idt_gate_t; + +struct frame { + uint64_t rbp; + uint64_t rbx; + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; + uint64_t int_number; + uint64_t err; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} __attribute__((packed)); + +static idt_gate_t idt[256]; +void *isr[256]; +extern void *isr_stubs[]; +static idt_ptr_t idtr; + +#define NO_NAME "Не задано название" + +const char *exception_names[] = { "Деление на ноль", + "Отладка", + "NMI", + "Точка останова", + "Переполнение", + "Выход за границы", + "Недопустимая операция", + "Устройство недоступно", + "Двойное исключение", + NO_NAME, + "Недопустимый TSS", + "Сегмент не присутствует", + "Ошибка сегмента стека", + "Общая защитная ошибка", + "Ошибка страницы", + NO_NAME, + "x87 исключение", + "Проверка выравнивания", + "Ошибка машины", + "SIMD исключение", + "Виртуализация", + NO_NAME, + NO_NAME, + NO_NAME, + NO_NAME, + NO_NAME, + NO_NAME, + NO_NAME, + NO_NAME, + "Безопасность" }; + +void idt_load( ) { + asm volatile("lidt %0" : : "m"(idtr)); + asm volatile("sti"); +} + +static void encode_idt_entry(uint8_t vector, void *handler, uint8_t flags) { + uint64_t ptr = (uint64_t)handler; + + idt[vector].offset_16 = (uint16_t)ptr; + idt[vector].selector = 0x28; + idt[vector].ist = 0; + idt[vector].flags = flags; + idt[vector].offset_middle_16 = (uint16_t)(ptr >> 16); + idt[vector].offset_high_32 = (uint32_t)(ptr >> 32); + idt[vector].reserved = 0; +} + +static void exception_handler(struct frame state) { + fb::printf("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", + exception_names[state.int_number]); + + fb::printf(" RAX=%x RBX=%x\n" + " RCX=%x RDX=%x\n" + " RSI=%x RDI=%x\n" + " RBP=%x RSP=%x\n" + " R08=%x R09=%x\n" + " R10=%x R11=%x\n" + " R12=%x R13=%x\n" + " R14=%x R15=%x\n" + " RIP=%x RFLAGS=%x\n" + " CS=%x SS=%x\n" + " ERR=%x INT=%u", + state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, + state.rbp, state.rsp, state.r8, state.r9, state.r10, state.r11, + state.r12, state.r13, state.r14, state.r15, state.rip, + state.rflags, state.cs, state.ss, state.err, state.int_number); + + asm volatile("cli; hlt"); +} + +void isr_generic(struct frame state) { + if (state.int_number < 32) { + exception_handler(state); + } else { + fb::printf("\nПрерывание! %u необработано :(\n", state.int_number); + } +} + +void idt_init( ) { + idtr = (idt_ptr_t){ .limit = sizeof(idt) - 1, .base = (uint64_t)idt }; + + for (uint64_t i = 0; i < 256; i++) { + if (i < 32) { + encode_idt_entry(i, isr_stubs[i], 0x8e); + isr[i] = (void *)exception_handler; + } else { + encode_idt_entry(i, isr_stubs[i], 0x8e); + isr[i] = (void *)isr_generic; + } + } + + idt_load( ); + fb::printf("IDT инициализирован.\n"); +} + +void idt_set_ist(uint8_t vector, uint8_t ist) { + idt[vector].ist = ist; +} +} diff --git a/kernel/arch/idt_stubs.s b/kernel/arch/idt_stubs.s new file mode 100644 index 0000000..06b17ac --- /dev/null +++ b/kernel/arch/idt_stubs.s @@ -0,0 +1,1573 @@ + .text + .code64 + .global isr_stubs + .extern isr_generic + +common: + subq $120, %rsp + movq %rbp, 0(%rsp) + movq %rbx, 8(%rsp) + movq %r15, 16(%rsp) + movq %r14, 24(%rsp) + movq %r13, 32(%rsp) + movq %r12, 40(%rsp) + movq %r11, 48(%rsp) + movq %r10, 56(%rsp) + movq %r9, 64(%rsp) + movq %r8, 72(%rsp) + movq %rax, 80(%rsp) + movq %rcx, 88(%rsp) + movq %rdx, 96(%rsp) + movq %rsi, 104(%rsp) + movq %rdi, 112(%rsp) + cld + movq %rsp, %rdi + call isr_generic + movq 0(%rsp), %rbp + movq 8(%rsp), %rbx + movq 16(%rsp), %r15 + movq 24(%rsp), %r14 + movq 32(%rsp), %r13 + movq 40(%rsp), %r12 + movq 48(%rsp), %r11 + movq 56(%rsp), %r10 + movq 64(%rsp), %r9 + movq 72(%rsp), %r8 + movq 80(%rsp), %rax + movq 88(%rsp), %rcx + movq 96(%rsp), %rdx + movq 104(%rsp), %rsi + movq 112(%rsp), %rdi + addq $136, %rsp + iretq + .align 16 +entry0: + pushq $0 + pushq $0 + jmp common + .align 16 +entry1: + pushq $0 + pushq $1 + jmp common + .align 16 +entry2: + pushq $0 + pushq $2 + jmp common + .align 16 +entry3: + pushq $0 + pushq $3 + jmp common + .align 16 +entry4: + pushq $0 + pushq $4 + jmp common + .align 16 +entry5: + pushq $0 + pushq $5 + jmp common + .align 16 +entry6: + pushq $0 + pushq $6 + jmp common + .align 16 +entry7: + pushq $0 + pushq $7 + jmp common + .align 16 +entry8: + pushq $8 + jmp common + .align 16 +entry9: + pushq $0 + pushq $9 + jmp common + .align 16 +entry10: + pushq $10 + jmp common + .align 16 +entry11: + pushq $11 + jmp common + .align 16 +entry12: + pushq $12 + jmp common + .align 16 +entry13: + pushq $13 + jmp common + .align 16 +entry14: + pushq $14 + jmp common + .align 16 +entry15: + pushq $0 + pushq $15 + jmp common + .align 16 +entry16: + pushq $0 + pushq $16 + jmp common + .align 16 +entry17: + pushq $17 + jmp common + .align 16 +entry18: + pushq $0 + pushq $18 + jmp common + .align 16 +entry19: + pushq $0 + pushq $19 + jmp common + .align 16 +entry20: + pushq $0 + pushq $20 + jmp common + .align 16 +entry21: + pushq $0 + pushq $21 + jmp common + .align 16 +entry22: + pushq $0 + pushq $22 + jmp common + .align 16 +entry23: + pushq $0 + pushq $23 + jmp common + .align 16 +entry24: + pushq $0 + pushq $24 + jmp common + .align 16 +entry25: + pushq $0 + pushq $25 + jmp common + .align 16 +entry26: + pushq $0 + pushq $26 + jmp common + .align 16 +entry27: + pushq $0 + pushq $27 + jmp common + .align 16 +entry28: + pushq $0 + pushq $28 + jmp common + .align 16 +entry29: + pushq $0 + pushq $29 + jmp common + .align 16 +entry30: + pushq $0 + pushq $30 + jmp common + .align 16 +entry31: + pushq $0 + pushq $31 + jmp common + .align 16 +entry32: + pushq $0 + pushq $32 + jmp common + .align 16 +entry33: + pushq $0 + pushq $33 + jmp common + .align 16 +entry34: + pushq $0 + pushq $34 + jmp common + .align 16 +entry35: + pushq $0 + pushq $35 + jmp common + .align 16 +entry36: + pushq $0 + pushq $36 + jmp common + .align 16 +entry37: + pushq $0 + pushq $37 + jmp common + .align 16 +entry38: + pushq $0 + pushq $38 + jmp common + .align 16 +entry39: + pushq $0 + pushq $39 + jmp common + .align 16 +entry40: + pushq $0 + pushq $40 + jmp common + .align 16 +entry41: + pushq $0 + pushq $41 + jmp common + .align 16 +entry42: + pushq $0 + pushq $42 + jmp common + .align 16 +entry43: + pushq $0 + pushq $43 + jmp common + .align 16 +entry44: + pushq $0 + pushq $44 + jmp common + .align 16 +entry45: + pushq $0 + pushq $45 + jmp common + .align 16 +entry46: + pushq $0 + pushq $46 + jmp common + .align 16 +entry47: + pushq $0 + pushq $47 + jmp common + .align 16 +entry48: + pushq $0 + pushq $48 + jmp common + .align 16 +entry49: + pushq $0 + pushq $49 + jmp common + .align 16 +entry50: + pushq $0 + pushq $50 + jmp common + .align 16 +entry51: + pushq $0 + pushq $51 + jmp common + .align 16 +entry52: + pushq $0 + pushq $52 + jmp common + .align 16 +entry53: + pushq $0 + pushq $53 + jmp common + .align 16 +entry54: + pushq $0 + pushq $54 + jmp common + .align 16 +entry55: + pushq $0 + pushq $55 + jmp common + .align 16 +entry56: + pushq $0 + pushq $56 + jmp common + .align 16 +entry57: + pushq $0 + pushq $57 + jmp common + .align 16 +entry58: + pushq $0 + pushq $58 + jmp common + .align 16 +entry59: + pushq $0 + pushq $59 + jmp common + .align 16 +entry60: + pushq $0 + pushq $60 + jmp common + .align 16 +entry61: + pushq $0 + pushq $61 + jmp common + .align 16 +entry62: + pushq $0 + pushq $62 + jmp common + .align 16 +entry63: + pushq $0 + pushq $63 + jmp common + .align 16 +entry64: + pushq $0 + pushq $64 + jmp common + .align 16 +entry65: + pushq $0 + pushq $65 + jmp common + .align 16 +entry66: + pushq $0 + pushq $66 + jmp common + .align 16 +entry67: + pushq $0 + pushq $67 + jmp common + .align 16 +entry68: + pushq $0 + pushq $68 + jmp common + .align 16 +entry69: + pushq $0 + pushq $69 + jmp common + .align 16 +entry70: + pushq $0 + pushq $70 + jmp common + .align 16 +entry71: + pushq $0 + pushq $71 + jmp common + .align 16 +entry72: + pushq $0 + pushq $72 + jmp common + .align 16 +entry73: + pushq $0 + pushq $73 + jmp common + .align 16 +entry74: + pushq $0 + pushq $74 + jmp common + .align 16 +entry75: + pushq $0 + pushq $75 + jmp common + .align 16 +entry76: + pushq $0 + pushq $76 + jmp common + .align 16 +entry77: + pushq $0 + pushq $77 + jmp common + .align 16 +entry78: + pushq $0 + pushq $78 + jmp common + .align 16 +entry79: + pushq $0 + pushq $79 + jmp common + .align 16 +entry80: + pushq $0 + pushq $80 + jmp common + .align 16 +entry81: + pushq $0 + pushq $81 + jmp common + .align 16 +entry82: + pushq $0 + pushq $82 + jmp common + .align 16 +entry83: + pushq $0 + pushq $83 + jmp common + .align 16 +entry84: + pushq $0 + pushq $84 + jmp common + .align 16 +entry85: + pushq $0 + pushq $85 + jmp common + .align 16 +entry86: + pushq $0 + pushq $86 + jmp common + .align 16 +entry87: + pushq $0 + pushq $87 + jmp common + .align 16 +entry88: + pushq $0 + pushq $88 + jmp common + .align 16 +entry89: + pushq $0 + pushq $89 + jmp common + .align 16 +entry90: + pushq $0 + pushq $90 + jmp common + .align 16 +entry91: + pushq $0 + pushq $91 + jmp common + .align 16 +entry92: + pushq $0 + pushq $92 + jmp common + .align 16 +entry93: + pushq $0 + pushq $93 + jmp common + .align 16 +entry94: + pushq $0 + pushq $94 + jmp common + .align 16 +entry95: + pushq $0 + pushq $95 + jmp common + .align 16 +entry96: + pushq $0 + pushq $96 + jmp common + .align 16 +entry97: + pushq $0 + pushq $97 + jmp common + .align 16 +entry98: + pushq $0 + pushq $98 + jmp common + .align 16 +entry99: + pushq $0 + pushq $99 + jmp common + .align 16 +entry100: + pushq $0 + pushq $100 + jmp common + .align 16 +entry101: + pushq $0 + pushq $101 + jmp common + .align 16 +entry102: + pushq $0 + pushq $102 + jmp common + .align 16 +entry103: + pushq $0 + pushq $103 + jmp common + .align 16 +entry104: + pushq $0 + pushq $104 + jmp common + .align 16 +entry105: + pushq $0 + pushq $105 + jmp common + .align 16 +entry106: + pushq $0 + pushq $106 + jmp common + .align 16 +entry107: + pushq $0 + pushq $107 + jmp common + .align 16 +entry108: + pushq $0 + pushq $108 + jmp common + .align 16 +entry109: + pushq $0 + pushq $109 + jmp common + .align 16 +entry110: + pushq $0 + pushq $110 + jmp common + .align 16 +entry111: + pushq $0 + pushq $111 + jmp common + .align 16 +entry112: + pushq $0 + pushq $112 + jmp common + .align 16 +entry113: + pushq $0 + pushq $113 + jmp common + .align 16 +entry114: + pushq $0 + pushq $114 + jmp common + .align 16 +entry115: + pushq $0 + pushq $115 + jmp common + .align 16 +entry116: + pushq $0 + pushq $116 + jmp common + .align 16 +entry117: + pushq $0 + pushq $117 + jmp common + .align 16 +entry118: + pushq $0 + pushq $118 + jmp common + .align 16 +entry119: + pushq $0 + pushq $119 + jmp common + .align 16 +entry120: + pushq $0 + pushq $120 + jmp common + .align 16 +entry121: + pushq $0 + pushq $121 + jmp common + .align 16 +entry122: + pushq $0 + pushq $122 + jmp common + .align 16 +entry123: + pushq $0 + pushq $123 + jmp common + .align 16 +entry124: + pushq $0 + pushq $124 + jmp common + .align 16 +entry125: + pushq $0 + pushq $125 + jmp common + .align 16 +entry126: + pushq $0 + pushq $126 + jmp common + .align 16 +entry127: + pushq $0 + pushq $127 + jmp common + .align 16 +entry128: + pushq $0 + pushq $128 + jmp common + .align 16 +entry129: + pushq $0 + pushq $129 + jmp common + .align 16 +entry130: + pushq $0 + pushq $130 + jmp common + .align 16 +entry131: + pushq $0 + pushq $131 + jmp common + .align 16 +entry132: + pushq $0 + pushq $132 + jmp common + .align 16 +entry133: + pushq $0 + pushq $133 + jmp common + .align 16 +entry134: + pushq $0 + pushq $134 + jmp common + .align 16 +entry135: + pushq $0 + pushq $135 + jmp common + .align 16 +entry136: + pushq $0 + pushq $136 + jmp common + .align 16 +entry137: + pushq $0 + pushq $137 + jmp common + .align 16 +entry138: + pushq $0 + pushq $138 + jmp common + .align 16 +entry139: + pushq $0 + pushq $139 + jmp common + .align 16 +entry140: + pushq $0 + pushq $140 + jmp common + .align 16 +entry141: + pushq $0 + pushq $141 + jmp common + .align 16 +entry142: + pushq $0 + pushq $142 + jmp common + .align 16 +entry143: + pushq $0 + pushq $143 + jmp common + .align 16 +entry144: + pushq $0 + pushq $144 + jmp common + .align 16 +entry145: + pushq $0 + pushq $145 + jmp common + .align 16 +entry146: + pushq $0 + pushq $146 + jmp common + .align 16 +entry147: + pushq $0 + pushq $147 + jmp common + .align 16 +entry148: + pushq $0 + pushq $148 + jmp common + .align 16 +entry149: + pushq $0 + pushq $149 + jmp common + .align 16 +entry150: + pushq $0 + pushq $150 + jmp common + .align 16 +entry151: + pushq $0 + pushq $151 + jmp common + .align 16 +entry152: + pushq $0 + pushq $152 + jmp common + .align 16 +entry153: + pushq $0 + pushq $153 + jmp common + .align 16 +entry154: + pushq $0 + pushq $154 + jmp common + .align 16 +entry155: + pushq $0 + pushq $155 + jmp common + .align 16 +entry156: + pushq $0 + pushq $156 + jmp common + .align 16 +entry157: + pushq $0 + pushq $157 + jmp common + .align 16 +entry158: + pushq $0 + pushq $158 + jmp common + .align 16 +entry159: + pushq $0 + pushq $159 + jmp common + .align 16 +entry160: + pushq $0 + pushq $160 + jmp common + .align 16 +entry161: + pushq $0 + pushq $161 + jmp common + .align 16 +entry162: + pushq $0 + pushq $162 + jmp common + .align 16 +entry163: + pushq $0 + pushq $163 + jmp common + .align 16 +entry164: + pushq $0 + pushq $164 + jmp common + .align 16 +entry165: + pushq $0 + pushq $165 + jmp common + .align 16 +entry166: + pushq $0 + pushq $166 + jmp common + .align 16 +entry167: + pushq $0 + pushq $167 + jmp common + .align 16 +entry168: + pushq $0 + pushq $168 + jmp common + .align 16 +entry169: + pushq $0 + pushq $169 + jmp common + .align 16 +entry170: + pushq $0 + pushq $170 + jmp common + .align 16 +entry171: + pushq $0 + pushq $171 + jmp common + .align 16 +entry172: + pushq $0 + pushq $172 + jmp common + .align 16 +entry173: + pushq $0 + pushq $173 + jmp common + .align 16 +entry174: + pushq $0 + pushq $174 + jmp common + .align 16 +entry175: + pushq $0 + pushq $175 + jmp common + .align 16 +entry176: + pushq $0 + pushq $176 + jmp common + .align 16 +entry177: + pushq $0 + pushq $177 + jmp common + .align 16 +entry178: + pushq $0 + pushq $178 + jmp common + .align 16 +entry179: + pushq $0 + pushq $179 + jmp common + .align 16 +entry180: + pushq $0 + pushq $180 + jmp common + .align 16 +entry181: + pushq $0 + pushq $181 + jmp common + .align 16 +entry182: + pushq $0 + pushq $182 + jmp common + .align 16 +entry183: + pushq $0 + pushq $183 + jmp common + .align 16 +entry184: + pushq $0 + pushq $184 + jmp common + .align 16 +entry185: + pushq $0 + pushq $185 + jmp common + .align 16 +entry186: + pushq $0 + pushq $186 + jmp common + .align 16 +entry187: + pushq $0 + pushq $187 + jmp common + .align 16 +entry188: + pushq $0 + pushq $188 + jmp common + .align 16 +entry189: + pushq $0 + pushq $189 + jmp common + .align 16 +entry190: + pushq $0 + pushq $190 + jmp common + .align 16 +entry191: + pushq $0 + pushq $191 + jmp common + .align 16 +entry192: + pushq $0 + pushq $192 + jmp common + .align 16 +entry193: + pushq $0 + pushq $193 + jmp common + .align 16 +entry194: + pushq $0 + pushq $194 + jmp common + .align 16 +entry195: + pushq $0 + pushq $195 + jmp common + .align 16 +entry196: + pushq $0 + pushq $196 + jmp common + .align 16 +entry197: + pushq $0 + pushq $197 + jmp common + .align 16 +entry198: + pushq $0 + pushq $198 + jmp common + .align 16 +entry199: + pushq $0 + pushq $199 + jmp common + .align 16 +entry200: + pushq $0 + pushq $200 + jmp common + .align 16 +entry201: + pushq $0 + pushq $201 + jmp common + .align 16 +entry202: + pushq $0 + pushq $202 + jmp common + .align 16 +entry203: + pushq $0 + pushq $203 + jmp common + .align 16 +entry204: + pushq $0 + pushq $204 + jmp common + .align 16 +entry205: + pushq $0 + pushq $205 + jmp common + .align 16 +entry206: + pushq $0 + pushq $206 + jmp common + .align 16 +entry207: + pushq $0 + pushq $207 + jmp common + .align 16 +entry208: + pushq $0 + pushq $208 + jmp common + .align 16 +entry209: + pushq $0 + pushq $209 + jmp common + .align 16 +entry210: + pushq $0 + pushq $210 + jmp common + .align 16 +entry211: + pushq $0 + pushq $211 + jmp common + .align 16 +entry212: + pushq $0 + pushq $212 + jmp common + .align 16 +entry213: + pushq $0 + pushq $213 + jmp common + .align 16 +entry214: + pushq $0 + pushq $214 + jmp common + .align 16 +entry215: + pushq $0 + pushq $215 + jmp common + .align 16 +entry216: + pushq $0 + pushq $216 + jmp common + .align 16 +entry217: + pushq $0 + pushq $217 + jmp common + .align 16 +entry218: + pushq $0 + pushq $218 + jmp common + .align 16 +entry219: + pushq $0 + pushq $219 + jmp common + .align 16 +entry220: + pushq $0 + pushq $220 + jmp common + .align 16 +entry221: + pushq $0 + pushq $221 + jmp common + .align 16 +entry222: + pushq $0 + pushq $222 + jmp common + .align 16 +entry223: + pushq $0 + pushq $223 + jmp common + .align 16 +entry224: + pushq $0 + pushq $224 + jmp common + .align 16 +entry225: + pushq $0 + pushq $225 + jmp common + .align 16 +entry226: + pushq $0 + pushq $226 + jmp common + .align 16 +entry227: + pushq $0 + pushq $227 + jmp common + .align 16 +entry228: + pushq $0 + pushq $228 + jmp common + .align 16 +entry229: + pushq $0 + pushq $229 + jmp common + .align 16 +entry230: + pushq $0 + pushq $230 + jmp common + .align 16 +entry231: + pushq $0 + pushq $231 + jmp common + .align 16 +entry232: + pushq $0 + pushq $232 + jmp common + .align 16 +entry233: + pushq $0 + pushq $233 + jmp common + .align 16 +entry234: + pushq $0 + pushq $234 + jmp common + .align 16 +entry235: + pushq $0 + pushq $235 + jmp common + .align 16 +entry236: + pushq $0 + pushq $236 + jmp common + .align 16 +entry237: + pushq $0 + pushq $237 + jmp common + .align 16 +entry238: + pushq $0 + pushq $238 + jmp common + .align 16 +entry239: + pushq $0 + pushq $239 + jmp common + .align 16 +entry240: + pushq $0 + pushq $240 + jmp common + .align 16 +entry241: + pushq $0 + pushq $241 + jmp common + .align 16 +entry242: + pushq $0 + pushq $242 + jmp common + .align 16 +entry243: + pushq $0 + pushq $243 + jmp common + .align 16 +entry244: + pushq $0 + pushq $244 + jmp common + .align 16 +entry245: + pushq $0 + pushq $245 + jmp common + .align 16 +entry246: + pushq $0 + pushq $246 + jmp common + .align 16 +entry247: + pushq $0 + pushq $247 + jmp common + .align 16 +entry248: + pushq $0 + pushq $248 + jmp common + .align 16 +entry249: + pushq $0 + pushq $249 + jmp common + .align 16 +entry250: + pushq $0 + pushq $250 + jmp common + .align 16 +entry251: + pushq $0 + pushq $251 + jmp common + .align 16 +entry252: + pushq $0 + pushq $252 + jmp common + .align 16 +entry253: + pushq $0 + pushq $253 + jmp common + .align 16 +entry254: + pushq $0 + pushq $254 + jmp common + .align 16 +entry255: + pushq $0 + pushq $255 + jmp common + .align 16 +isr_stubs: + .quad entry0 + .quad entry1 + .quad entry2 + .quad entry3 + .quad entry4 + .quad entry5 + .quad entry6 + .quad entry7 + .quad entry8 + .quad entry9 + .quad entry10 + .quad entry11 + .quad entry12 + .quad entry13 + .quad entry14 + .quad entry15 + .quad entry16 + .quad entry17 + .quad entry18 + .quad entry19 + .quad entry20 + .quad entry21 + .quad entry22 + .quad entry23 + .quad entry24 + .quad entry25 + .quad entry26 + .quad entry27 + .quad entry28 + .quad entry29 + .quad entry30 + .quad entry31 + .quad entry32 + .quad entry33 + .quad entry34 + .quad entry35 + .quad entry36 + .quad entry37 + .quad entry38 + .quad entry39 + .quad entry40 + .quad entry41 + .quad entry42 + .quad entry43 + .quad entry44 + .quad entry45 + .quad entry46 + .quad entry47 + .quad entry48 + .quad entry49 + .quad entry50 + .quad entry51 + .quad entry52 + .quad entry53 + .quad entry54 + .quad entry55 + .quad entry56 + .quad entry57 + .quad entry58 + .quad entry59 + .quad entry60 + .quad entry61 + .quad entry62 + .quad entry63 + .quad entry64 + .quad entry65 + .quad entry66 + .quad entry67 + .quad entry68 + .quad entry69 + .quad entry70 + .quad entry71 + .quad entry72 + .quad entry73 + .quad entry74 + .quad entry75 + .quad entry76 + .quad entry77 + .quad entry78 + .quad entry79 + .quad entry80 + .quad entry81 + .quad entry82 + .quad entry83 + .quad entry84 + .quad entry85 + .quad entry86 + .quad entry87 + .quad entry88 + .quad entry89 + .quad entry90 + .quad entry91 + .quad entry92 + .quad entry93 + .quad entry94 + .quad entry95 + .quad entry96 + .quad entry97 + .quad entry98 + .quad entry99 + .quad entry100 + .quad entry101 + .quad entry102 + .quad entry103 + .quad entry104 + .quad entry105 + .quad entry106 + .quad entry107 + .quad entry108 + .quad entry109 + .quad entry110 + .quad entry111 + .quad entry112 + .quad entry113 + .quad entry114 + .quad entry115 + .quad entry116 + .quad entry117 + .quad entry118 + .quad entry119 + .quad entry120 + .quad entry121 + .quad entry122 + .quad entry123 + .quad entry124 + .quad entry125 + .quad entry126 + .quad entry127 + .quad entry128 + .quad entry129 + .quad entry130 + .quad entry131 + .quad entry132 + .quad entry133 + .quad entry134 + .quad entry135 + .quad entry136 + .quad entry137 + .quad entry138 + .quad entry139 + .quad entry140 + .quad entry141 + .quad entry142 + .quad entry143 + .quad entry144 + .quad entry145 + .quad entry146 + .quad entry147 + .quad entry148 + .quad entry149 + .quad entry150 + .quad entry151 + .quad entry152 + .quad entry153 + .quad entry154 + .quad entry155 + .quad entry156 + .quad entry157 + .quad entry158 + .quad entry159 + .quad entry160 + .quad entry161 + .quad entry162 + .quad entry163 + .quad entry164 + .quad entry165 + .quad entry166 + .quad entry167 + .quad entry168 + .quad entry169 + .quad entry170 + .quad entry171 + .quad entry172 + .quad entry173 + .quad entry174 + .quad entry175 + .quad entry176 + .quad entry177 + .quad entry178 + .quad entry179 + .quad entry180 + .quad entry181 + .quad entry182 + .quad entry183 + .quad entry184 + .quad entry185 + .quad entry186 + .quad entry187 + .quad entry188 + .quad entry189 + .quad entry190 + .quad entry191 + .quad entry192 + .quad entry193 + .quad entry194 + .quad entry195 + .quad entry196 + .quad entry197 + .quad entry198 + .quad entry199 + .quad entry200 + .quad entry201 + .quad entry202 + .quad entry203 + .quad entry204 + .quad entry205 + .quad entry206 + .quad entry207 + .quad entry208 + .quad entry209 + .quad entry210 + .quad entry211 + .quad entry212 + .quad entry213 + .quad entry214 + .quad entry215 + .quad entry216 + .quad entry217 + .quad entry218 + .quad entry219 + .quad entry220 + .quad entry221 + .quad entry222 + .quad entry223 + .quad entry224 + .quad entry225 + .quad entry226 + .quad entry227 + .quad entry228 + .quad entry229 + .quad entry230 + .quad entry231 + .quad entry232 + .quad entry233 + .quad entry234 + .quad entry235 + .quad entry236 + .quad entry237 + .quad entry238 + .quad entry239 + .quad entry240 + .quad entry241 + .quad entry242 + .quad entry243 + .quad entry244 + .quad entry245 + .quad entry246 + .quad entry247 + .quad entry248 + .quad entry249 + .quad entry250 + .quad entry251 + .quad entry252 + .quad entry253 + .quad entry254 + .quad entry255 diff --git a/kernel/arch/load_gdt.s b/kernel/arch/load_gdt.s new file mode 100644 index 0000000..7768b1c --- /dev/null +++ b/kernel/arch/load_gdt.s @@ -0,0 +1,15 @@ +.global load_gdt +load_gdt: + cli + lgdt (%rdi) + movw $0x30, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + pop %rdi + mov $0x28, %rax + push %rax + push %rdi + retfq \ No newline at end of file diff --git a/kernel/main.c b/kernel/main.c new file mode 100644 index 0000000..c470634 --- /dev/null +++ b/kernel/main.c @@ -0,0 +1,10 @@ + +void assert(int x) {} + +void *malloc(int size) {} + +void *realloc(void *pointer, int new_size) {} + +void free(void *pointer) {} + +void main( ) {} \ No newline at end of file diff --git a/kernel/mem.cpp b/kernel/mem.cpp index 2533aa8..377496d 100644 --- a/kernel/mem.cpp +++ b/kernel/mem.cpp @@ -4,6 +4,7 @@ #include #define BLOCK_SIZE 4096 + static volatile struct limine_memmap_request memmap_request = { .id = LIMINE_MEMMAP_REQUEST, .revision = 0, @@ -20,34 +21,129 @@ namespace mem { #define HHDM_OFFSET (hhdm_request.response->offset) struct limine_memmap_response *memmap_response; -struct limine_memmap_entry *memmap_entry; + +// Битовая карта для отслеживания занятых и свободных фреймов памяти uint8_t *bitmap; +// Объем доступных блоков +uint64_t bitmap_available = 0; +// Объем блоков +uint64_t bitmap_limit = 0; +// Верхняя граница доступной памяти uint64_t limit; +// Объем всего доступного физического адресного пространства uint64_t usable = 0; +// Объем доступной виртуальной памяти uint64_t available = 0; +// Наивысший адрес в available space uint64_t highest = 0; +// Количество записей в карте памяти uint64_t mmmap_count = 0; -lock_t lock = LOCK_INIT; +// Массив с описаниями типов памяти +char memory_types[8][82] = { + "Доступно", "Зарезервировано", "ACPI, можно освободить", + "ACPI NVS", "Плохая память", "Загрузчик, можно освободить", + "Ядро и модули", "Буфер кадра" +}; -void init( ) { - memmap_response = memmap_request.response; - mmmap_count = memmap_response->entry_count; - - fb::printf("В карте памяти: %u записей.\n", memmap_response->entry_count); +void free(void *ptr, uint64_t frames) { + // Проход по фреймам памяти и очистка битов в битовой карте + uint64_t frame = (uint64_t)ptr / BLOCK_SIZE; + for (uint64_t i = frame; i < frames + frame; i++) { BIT_CLEAR(i); } + bitmap_available++; } -void free(void *ptr, uint64_t frames) {} +// Функция выделения памяти +void *alloc(uint64_t wanted_frames) { + void *ptr; -void *malloc(uint64_t count) { + uint64_t available_frames = 0; + for (uint64_t frame = 1; frame < limit; frame++) { + if (!BIT_GET(frame)) { + available_frames++; + } else if (available_frames != wanted_frames) { + available_frames = 0; + continue; + } + if (available_frames == wanted_frames) { + uint64_t i; + for (i = 0; i < wanted_frames; i++) { BIT_SET(frame - i); } + frame -= i - 1; + + ptr = (void *)(BLOCK_SIZE * frame); + return ptr; + } + } return NULL; } void *calloc(uint64_t frames) { - return (void *)0; + void *ptr = alloc(frames); + tool::memset(ptr + HHDM_OFFSET, 0, frames * BLOCK_SIZE); + return ptr; } -void *alloc(uint64_t size) { - return (void *)0; +// Инициализация менеджера памяти +void init( ) { + // Получение информации о доступной памяти из Limine bootloader + memmap_response = memmap_request.response; + mmmap_count = memmap_response->entry_count; + struct limine_memmap_entry **mmaps = memmap_response->entries; + + fb::printf("В карте памяти: %u записей.\n", memmap_response->entry_count); + + // Обработка каждой записи в карте памяти + for (int i = 0; i < mmmap_count; i++) { + available += mmaps[i]->length; + + // fb::printf("\t%d: 0x%x\tдлина: 0x%x\tтип: %s\n", i + 1, + // mmaps[i]->base, mmaps[i]->length, memory_types[mmaps[i]->type]); + + // Пропускаем записи, не являющиеся доступными памятью + if (!mmaps[i]->type == LIMINE_MEMMAP_USABLE) { continue; } + + usable += mmaps[i]->length; + uint64_t top = mmaps[i]->base + mmaps[i]->length; + if (top > highest) highest = top; + } + + limit = highest / BLOCK_SIZE; + uint64_t bitmap_size = ALIGN_UP(highest / BLOCK_SIZE / 8, BLOCK_SIZE); + + // Находим доступное место для битовой карты и устанавливаем ее + for (uint64_t i = 0; i < mmmap_count; i++) { + if (!mmaps[i]->type == LIMINE_MEMMAP_USABLE) continue; + + if (mmaps[i]->length >= bitmap_size) { + bitmap = (uint8_t *)mmaps[i]->base; + tool::memset(bitmap, 0xFF, bitmap_size); + mmaps[i]->length -= bitmap_size; + mmaps[i]->base += bitmap_size; + available -= bitmap_size; + break; + } + } + + // Освобождаем все доступные фреймы памяти + for (uint64_t i = 0; i < mmmap_count; i++) { + for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { + bitmap_limit++; + } + if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE || + mmaps[i]->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE)) { + continue; + } + + for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { + free((void *)mmaps[i]->base + t, 1); + } + } + + fb::printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", + usable / 1024 / 1024, available / 1024 / 1024); + + fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); + fb::printf("Размер битовой карты: %u\n", bitmap_size); } + } // namespace mem \ No newline at end of file diff --git a/kernel/start.cpp b/kernel/start.cpp index f6c5a93..4ecb86b 100644 --- a/kernel/start.cpp +++ b/kernel/start.cpp @@ -5,15 +5,36 @@ #include #include #include +#include + +extern "C" void main( ); + +void pause( ) { + for (uint64_t i = 0; i < 1024; i++) { + for (uint64_t j = 0; j < 1024; j++) { + // for (uint64_t q = 0; q < 1; q++) { asm volatile("pause"); } + } + } +} // Точка входа extern "C" void _start( ) { asm volatile("cli"); fb::init( ); - fb::printf("Привет, мир!!\n"); + pause( ); + arch::init( ); + pause( ); cpu::init( ); + pause( ); mem::init( ); + fb::printf("\t\t\t\t *** БМПОС %u.%u.%u.%u ***\n", VERSION_MAJOR, + VERSION_MINOR, VERSION_BUILD); + fb::printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__); + mod::init( ); + pause( ); + + asm volatile("int $0"); for (;;) { asm volatile("hlt"); } } \ No newline at end of file diff --git a/kernel/tool.cpp b/kernel/tool.cpp index c798d20..90a86d8 100644 --- a/kernel/tool.cpp +++ b/kernel/tool.cpp @@ -90,7 +90,7 @@ void format(void (*putc)(char c), const char *format_string, va_list args) { if (rem < 10) { buffer[i++] = '0' + rem; } else { - buffer[i++] = 'a' + (rem - 10); + buffer[i++] = 'A' + (rem - 10); } arg /= 16; } diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..44db64b --- /dev/null +++ b/run.sh @@ -0,0 +1,2 @@ +#!/bin/sh +qemu-system-x86_64 -cpu max -m 2G -smp 1 -bios ovmf/OVMF.fd -hda mseos.hdd \ No newline at end of file diff --git a/scripts/gen_isr.py b/scripts/gen_isr.py new file mode 100644 index 0000000..ed068fb --- /dev/null +++ b/scripts/gen_isr.py @@ -0,0 +1,18 @@ +# Генерируем код для isr_stubs +isr_stubs_code = '' +for i in range(256): + isr_stubs_code += f'\t.quad isr_stub_{i}\n' + +# Генерируем код для isr_stub +isr_stub_code = '' +for i in range(256): + isr_stub_code += f'stub {i}\n' + +# Сохраняем код в файл +with open('output.s', 'w') as file: + file.write('.section .text\n') + file.write(isr_stub_code) + file.write('.global isr_stubs\n') + file.write('.section .data\n') + file.write('isr_stubs:\n') + file.write(isr_stubs_code) \ No newline at end of file