From 1ca922bb15fc65f6b17ac1b847b41e8afe3cfe55 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Sat, 21 Oct 2023 20:27:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B4=D0=BE=D0=B2=D0=BE=D0=B9=20=D0=B1=D0=B0=D0=B7?= =?UTF-8?q?=D1=8B=20=D0=BD=D0=B0=20=D1=8F=D0=B7=D1=8B=D0=BA=20C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 4 +- API.md | 4 +- README.md | 2 + include/arch.h | 21 +- include/cpu.h | 3 - include/fb.h | 24 ++- include/lock.h | 22 +- include/mem.h | 38 +++- include/mod.h | 18 +- include/sys.h | 16 +- include/tool.h | 37 ++-- include/version.h | 2 +- kernel/arch/{arch.cpp => arch.c} | 13 +- kernel/arch/cpu.c | 217 +++++++++++++++++++ kernel/arch/cpu.cpp | 223 -------------------- kernel/arch/{gdt.cpp => gdt.c} | 7 +- kernel/arch/{idt.cpp => idt.c} | 39 ++-- kernel/{fb.cpp => fb.c} | 298 +++++++++++++------------- kernel/{lock.cpp => lock.c} | 14 +- kernel/main/{main.cpp => main.c} | 40 ++-- kernel/{mem.cpp => mem.c} | 120 ++++++----- kernel/mod.c | 93 +++++++++ kernel/mod.cpp | 114 ---------- kernel/start.c | 24 +++ kernel/start.cpp | 25 --- kernel/sys.c | 30 +++ kernel/sys.cpp | 40 ---- kernel/task.c | 9 + kernel/task.cpp | 9 - kernel/{tool.cpp => tool.c} | 345 +++++++++++++++---------------- modules/com/main.cpp | 0 pbuild.py | 4 +- templates/temp.c | 12 ++ templates/temp.h | 14 ++ 34 files changed, 968 insertions(+), 913 deletions(-) delete mode 100644 include/cpu.h rename kernel/arch/{arch.cpp => arch.c} (77%) create mode 100644 kernel/arch/cpu.c delete mode 100644 kernel/arch/cpu.cpp rename kernel/arch/{gdt.cpp => gdt.c} (95%) rename kernel/arch/{idt.cpp => idt.c} (79%) rename kernel/{fb.cpp => fb.c} (84%) rename kernel/{lock.cpp => lock.c} (60%) rename kernel/main/{main.cpp => main.c} (81%) rename kernel/{mem.cpp => mem.c} (69%) create mode 100644 kernel/mod.c delete mode 100644 kernel/mod.cpp create mode 100644 kernel/start.c delete mode 100644 kernel/start.cpp create mode 100644 kernel/sys.c delete mode 100644 kernel/sys.cpp create mode 100644 kernel/task.c delete mode 100644 kernel/task.cpp rename kernel/{tool.cpp => tool.c} (89%) delete mode 100644 modules/com/main.cpp create mode 100644 templates/temp.c create mode 100644 templates/temp.h diff --git a/.vscode/settings.json b/.vscode/settings.json index aa7856f..dbf865d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,8 @@ "string_view": "cpp", "initializer_list": "cpp", "complex": "cpp", - "string": "cpp" + "string": "cpp", + "limine.h": "c", + "tool.h": "c" } } \ No newline at end of file diff --git a/API.md b/API.md index 11dbe9f..b5a5169 100644 --- a/API.md +++ b/API.md @@ -1,6 +1,6 @@ # Системные вызовы -## mem::alloc(size_t size) +## mem_alloc(size_t size) Выделение блока памяти размером `size`. Вовзращает адрес на блок памяти или 0 в случае ошибки. @@ -10,7 +10,7 @@ - `-1 не хватает ОЗУ`; - `-2 неправильный размер блока`. -## mem::free(uintptr_t mem) +## mem_free(uintptr_t mem) Освобождение блока памяти `mem`. Вовзращает 0 в случае успеха или -1 в случае ошибки. diff --git a/README.md b/README.md index d8062f6..9330426 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ БМПОС - Базовая Модульная Платформа Операционных Систем для платформы x86_64 (BIOS/UEFI). Это отечественное программное обеспечение, созданное при поддержке Синапс ОС на языке программирования C++. +![Скриншот вывода ядра в эмуляторе Qemu](https://0nera.github.io/BMOSP/assets/0_0.1.231.png + ## Реализовано Ядро: diff --git a/include/arch.h b/include/arch.h index 1588660..d51c53b 100644 --- a/include/arch.h +++ b/include/arch.h @@ -1,3 +1,18 @@ -namespace arch { -void init( ); -} \ No newline at end of file +/** + * arch.h + * Заголовок для инициализации архитектурно-зависимых функций + * + * Данный заголовочный файл содержит определения которые используются для + * инициализации архитектуры + * + */ + +#ifndef ARCH_H +#define ARCH_H + +void arch_init( ); +void cpu_init( ); +void gdt_init( ); +void idt_init( ); + +#endif // arch.h \ No newline at end of file diff --git a/include/cpu.h b/include/cpu.h deleted file mode 100644 index e9ecad4..0000000 --- a/include/cpu.h +++ /dev/null @@ -1,3 +0,0 @@ -namespace cpu { -void init( ); -} \ No newline at end of file diff --git a/include/fb.h b/include/fb.h index a42d25f..dd9fff6 100644 --- a/include/fb.h +++ b/include/fb.h @@ -1,12 +1,22 @@ +/** + * fb.h + * Заголовок с функциями фреймбуффера + * + * Данный заголовочный файл содержит определения которые используются для работы + * с экранным буффером(фреймбуффером) + * + */ + +#ifndef FB_H +#define FB_H + #include #include #include -namespace fb { +void fb_init( ); +void fb_print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf); +void fb_printf(char *str, ...); +void fb_printf_at(size_t x, size_t y, char *str, ...); -void init( ); -void print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf); -void printf(char *str, ...); - -void printf_at(size_t x, size_t y, char *str, ...); -} // namespace fb \ No newline at end of file +#endif // fb.h \ No newline at end of file diff --git a/include/lock.h b/include/lock.h index bc79e9b..2e05492 100644 --- a/include/lock.h +++ b/include/lock.h @@ -1,3 +1,15 @@ +/** + * lock.h + * Заголовок с функциями блокировок + * + * Данный заголовочный файл содержит определения которые используются для работы + * с блокировками ресурсов + * + */ + +#ifndef LOCK_H +#define LOCK_H + #include typedef struct { @@ -10,8 +22,8 @@ typedef struct { 0, __FILE__ \ } -namespace lock { -int swap(lock_t* lock); -void acquire(lock_t* lock); -void release(lock_t* lock); -} // namespace lock +int lock_swap(lock_t* lock); +void lock_acquire(lock_t* lock); +void lock_release(lock_t* lock); + +#endif // lock.h diff --git a/include/mem.h b/include/mem.h index 3471a67..e7deac6 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,10 +1,28 @@ -namespace mem { -void dump_memory( ); -void init( ); -void *alloc(size_t size); -void free(void *addr); -void *realloc(void *addr, size_t size); -void *frame_alloc(uint64_t wanted_frames); -void frame_free(void *ptr, uint64_t frames); -void *frame_calloc(uint64_t frames); -} // namespace mem \ No newline at end of file +/** + * mem.h + * Заголовочный файл с функциями менеджера памяти + * + * Данный заголовочный файл содержит определения, которые используются для + * работы с памятью + * + */ + +#ifndef MEM_H +#define MEM_H + +#include +#include + +#define BLOCK_SIZE 4096 +#define HHDM_OFFSET (hhdm_request.response->offset) + +void mem_dump_memory( ); +void mem_init( ); +void *mem_alloc(size_t size); +void mem_free(void *addr); +void *mem_realloc(void *addr, size_t size); +void *mem_frame_alloc(uint64_t wanted_frames); +void mem_frame_free(void *ptr, uint64_t frames); +void *mem_frame_calloc(uint64_t frames); + +#endif // mem.h \ No newline at end of file diff --git a/include/mod.h b/include/mod.h index b8823a1..4ddc843 100644 --- a/include/mod.h +++ b/include/mod.h @@ -1,3 +1,15 @@ -namespace mod { -void init( ); -} \ No newline at end of file +/** + * mod.h + * Заголовочный файл с функциями работы с памятью + * + * Данный заголовочный файл содержит определения, которые используются для + * работы с памятью + * + */ + +#ifndef MOD_H +#define MOD_H + +void mod_init( ); + +#endif // mod.h \ No newline at end of file diff --git a/include/sys.h b/include/sys.h index aa4d9ef..79c6f66 100644 --- a/include/sys.h +++ b/include/sys.h @@ -1,6 +1,17 @@ +/** + * sys.h + * Заголовок содержащий определения для работы системного API + * + * Данный заголовочный файл содержит определения которые используются для + * объявления структур и системных функций + * + */ + +#ifndef SYS_H +#define SYS_H + #include -extern "C" { typedef struct { void (*fb_printf)(char *str, ...); } env_t; @@ -42,4 +53,5 @@ typedef struct { uint8_t day; uint8_t second; } time_t; -} \ No newline at end of file + +#endif // sys.h \ No newline at end of file diff --git a/include/tool.h b/include/tool.h index 0429742..f127b01 100644 --- a/include/tool.h +++ b/include/tool.h @@ -1,20 +1,33 @@ +/** + * tool.h + * Заголовок содержащий определения вспомогательных функций + * + * Данный заголовочный файл содержит определения которые используются для + * упрощения написания кода + * + */ + +#ifndef TOOL_H +#define TOOL_H + #include +#include #define abs(x) ((x) < 0 ? -(x) : (x)) #define assert(check) \ - ({ \ + do { \ if (!(check)) { \ - fb::printf("\nassert() failed in %s() (%s:%d)\n", __func__, \ - __FILE__, __LINE__); \ + fb_printf("\nassert() failed in %s() (%s:%d)\n", __func__, \ + __FILE__, __LINE__); \ for (;;) asm volatile("hlt"); \ } \ - }) + } while (0) #define ALIGN_UP(NUM, ALIGN) (((NUM) + ALIGN - 1) & ~(ALIGN - 1)) #define ALIGN_DOWN(NUM, ALIGN) ((NUM) & ~(ALIGN - 1)) #define CONTAINER_OF(PTR, TYPE, MEMBER) \ - ((TYPE *)((void *)PTR - OFFSET_OF(TYPE, MEMBER))) + ((TYPE *)((void *)PTR - offsetof(TYPE, MEMBER))) #define BIT_SET(BIT) (bitmap[(BIT) / 8] |= (1 << ((BIT) % 8))) #define BIT_CLEAR(BIT) (bitmap[(BIT) / 8] &= ~(1 << ((BIT) % 8))) @@ -28,10 +41,10 @@ static inline void pause( ) { } } -namespace tool { -void memcpy(void *dest, void *src, uint64_t n); -void *memset(void *ptr, uint8_t n, uint64_t size); -uint64_t strlen(const char *str); -uint64_t starts_with(const char *str, const char *prefix); -void format(void (*putc)(char c), const char *format_string, va_list args); -} // namespace tool \ No newline at end of file +void tool_memcpy(void *dest, void *src, uint64_t n); +void *tool_memset(void *ptr, uint8_t n, uint64_t size); +uint64_t tool_strlen(const char *str); +uint64_t tool_starts_with(const char *str, const char *prefix); +void tool_format(void (*putc)(char c), const char *format_string, va_list args); + +#endif // tool.h diff --git a/include/version.h b/include/version.h index bd33d1b..6dcafcc 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 1 -#define VERSION_BUILD 231 +#define VERSION_BUILD 244 diff --git a/kernel/arch/arch.cpp b/kernel/arch/arch.c similarity index 77% rename from kernel/arch/arch.cpp rename to kernel/arch/arch.c index 7bb93c1..e4d83ff 100644 --- a/kernel/arch/arch.cpp +++ b/kernel/arch/arch.c @@ -1,12 +1,6 @@ +#include #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, @@ -15,9 +9,8 @@ static volatile struct limine_kernel_address_request kernel_address_request = { struct limine_kernel_address_response *kernel_address_response; -void init( ) { +void arch_init( ) { kernel_address_response = kernel_address_request.response; gdt_init( ); idt_init( ); -} -} // namespace arch \ No newline at end of file +} \ No newline at end of file diff --git a/kernel/arch/cpu.c b/kernel/arch/cpu.c new file mode 100644 index 0000000..ec66763 --- /dev/null +++ b/kernel/arch/cpu.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include + +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; + +static void sse_init( ) { + uint64_t _cr0 = 0; + asm volatile("mov %0, %%cr0" : "=r"(_cr0) : : "memory"); + _cr0 &= ~(1 << 2); + _cr0 |= (1 << 1); + asm volatile("mov %%cr0, %0" : : "r"(_cr0) : "memory"); + + uint64_t _cr4 = 0; + asm volatile("mov %0, %%cr4" : "=r"(_cr4) : : "memory"); + _cr4 |= (3 << 9); + asm volatile("mov %%cr4, %0" : : "r"(_cr4) : "memory"); +} + +static 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)); +} + +static void msr_get(uint32_t msr, uint32_t *lo, uint32_t *hi) { + asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); +} + +static void msr_set(uint32_t msr, uint32_t lo, uint32_t hi) { + asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); +} + +static uint64_t get_cpu_temperature( ) { + uint32_t lo, hi; + + // Чтение температуры из MSR + msr_get(0x19C, &lo, &hi); + + uint64_t temp = ((uint64_t)hi << 32) | (uint64_t)lo; + + // Преобразование значения температуры + uint64_t temperature = (temp >> 16) / 256; + + return temperature; +} + +static void l2_cache( ) { + unsigned int eax, ebx, ecx, edx; + unsigned int lsize, assoc, cache; + + cpuid(0x80000006, &eax, &ebx, &ecx, &edx); + lsize = ecx & 0xFF; + assoc = (ecx >> 12) & 0x07; + cache = (ecx >> 16) & 0xFFFF; + + fb_printf("Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", + lsize, assoc, cache); +} + +static 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); +} + +static 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 cpu_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( ); + } + + 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"); + } + + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + fb_printf("0x80000000 [EAX] = 0x%x (%u)\n", eax, eax); + + cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + + if ((edx >> 5) & 1) { fb_printf("Регистры MSR подерживаются!\n"); } + + if ((edx >> 6) & 1) { + fb_printf("Расширение физического адреса подерживается!\n"); + } + + if ((edx >> 7) & 1) { + fb_printf("Исключение проверки компьютера (MCE) подерживается!\n"); + } + + if ((edx >> 9) & 1) { + fb_printf("Усовершенствованный программируемый контроллер прерываний " + "подерживаются!\n"); + } + + if ((edx >> 10) & 1) { + fb_printf( + "SYSCALL/SYSRET(для AMD семейства 5 линейки 7) подерживаются!\n"); + } + if ((edx >> 11) & 1) { fb_printf("SYSCALL/SYSRET подерживаются!\n"); } + + if ((edx >> 26) & 1) { fb_printf("Гигабайтные страницы подерживаются!\n"); } + + if ((edx >> 29) & 1) { fb_printf("AMD64 подерживается!\n"); } + if ((edx >> 30) & 1) { fb_printf("\"3DNow!\" подерживается!\n"); } + if ((edx >> 31) & 1) { fb_printf("\"Extended 3DNow!\" подерживается!\n"); } + if ((ecx >> 6) & 1) { fb_printf("SSE4a подерживается!\n"); } + if ((ecx >> 7) & 1) { fb_printf("Смещенный режим SSE подерживается!\n"); } + + cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + if ((ebx >> 0) & 1) { + fb_printf("Восстановление после переполнения MCA подерживается!\n"); + } + if ((ebx >> 1) & 1) { + fb_printf("Возможность локализации и восстановления неисправимых " + "программных ошибок подерживается!\n"); + } + if ((edx >> 0) & 1) { fb_printf("Датчик температуры подерживается!\n"); } + if ((edx >> 3) & 1) { fb_printf("Терморегулятор подерживается!\n"); } + if ((edx >> 4) & 1) { + fb_printf("Аппаратный терморегулятор (HTC) подерживается!\n"); + } + if ((edx >> 5) & 1) { + fb_printf("Программный терморегулятор (STC) подерживается!\n"); + } + if ((edx >> 6) & 1) { + fb_printf("Управление множителем 100 МГц подерживается!\n"); + } + + fb_printf("0x80000007[ECX] = 0x%x (%u)\n", ecx, ecx); + + cpuid(0xC0000000, &eax, &ebx, &ecx, &edx); + if (eax > 0xC0000000) { + fb_printf("0xC0000000 [EAX] = 0x%x (%u)\n", eax, eax); + } + + brandname( ); + l2_cache( ); +} \ No newline at end of file diff --git a/kernel/arch/cpu.cpp b/kernel/arch/cpu.cpp deleted file mode 100644 index 40432dd..0000000 --- a/kernel/arch/cpu.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include -#include -#include -#include - -extern "C" { -void sse_init( ) { - uint64_t _cr0 = 0; - asm volatile("mov %0, %%cr0" : "=r"(_cr0) : : "memory"); - _cr0 &= ~(1 << 2); - _cr0 |= (1 << 1); - asm volatile("mov %%cr0, %0" : : "r"(_cr0) : "memory"); - - uint64_t _cr4 = 0; - asm volatile("mov %0, %%cr4" : "=r"(_cr4) : : "memory"); - _cr4 |= (3 << 9); - asm volatile("mov %%cr4, %0" : : "r"(_cr4) : "memory"); -} -} - -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(0x80000006, &eax, &ebx, &ecx, &edx); - lsize = ecx & 0xFF; - assoc = (ecx >> 12) & 0x07; - cache = (ecx >> 16) & 0xFFFF; - - fb::printf("Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", - lsize, assoc, cache); -} - -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 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( ); - } - - 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"); - } - - cpuid(0x80000000, &eax, &ebx, &ecx, &edx); - fb::printf("0x80000000 [EAX] = 0x%x (%u)\n", eax, eax); - - cpuid(0x80000001, &eax, &ebx, &ecx, &edx); - - if ((edx >> 5) & 1) { fb::printf("Регистры MSR подерживаются!\n"); } - - if ((edx >> 6) & 1) { - fb::printf("Расширение физического адреса подерживается!\n"); - } - - if ((edx >> 7) & 1) { - fb::printf("Исключение проверки компьютера (MCE) подерживается!\n"); - } - - if ((edx >> 9) & 1) { - fb::printf("Усовершенствованный программируемый контроллер прерываний " - "подерживаются!\n"); - } - - if ((edx >> 10) & 1) { - fb::printf( - "SYSCALL/SYSRET(для AMD семейства 5 линейки 7) подерживаются!\n"); - } - if ((edx >> 11) & 1) { fb::printf("SYSCALL/SYSRET подерживаются!\n"); } - - if ((edx >> 26) & 1) { - fb::printf("Гигабайтные страницы подерживаются!\n"); - } - - if ((edx >> 29) & 1) { fb::printf("AMD64 подерживается!\n"); } - if ((edx >> 30) & 1) { fb::printf("\"3DNow!\" подерживается!\n"); } - if ((edx >> 31) & 1) { fb::printf("\"Extended 3DNow!\" подерживается!\n"); } - if ((ecx >> 6) & 1) { fb::printf("SSE4a подерживается!\n"); } - if ((ecx >> 7) & 1) { fb::printf("Смещенный режим SSE подерживается!\n"); } - - cpuid(0x80000007, &eax, &ebx, &ecx, &edx); - if ((ebx >> 0) & 1) { - fb::printf("Восстановление после переполнения MCA подерживается!\n"); - } - if ((ebx >> 1) & 1) { - fb::printf("Возможность локализации и восстановления неисправимых " - "программных ошибок подерживается!\n"); - } - if ((edx >> 0) & 1) { fb::printf("Датчик температуры подерживается!\n"); } - if ((edx >> 3) & 1) { fb::printf("Терморегулятор подерживается!\n"); } - if ((edx >> 4) & 1) { - fb::printf("Аппаратный терморегулятор (HTC) подерживается!\n"); - } - if ((edx >> 5) & 1) { - fb::printf("Программный терморегулятор (STC) подерживается!\n"); - } - if ((edx >> 6) & 1) { - fb::printf("Управление множителем 100 МГц подерживается!\n"); - } - - fb::printf("0x80000007[ECX] = 0x%x (%u)\n", ecx, ecx); - - cpuid(0xC0000000, &eax, &ebx, &ecx, &edx); - if (eax > 0xC0000000) { - fb::printf("0xC0000000 [EAX] = 0x%x (%u)\n", eax, eax); - } - - brandname( ); - l2_cache( ); -} -} // namespace cpu \ No newline at end of file diff --git a/kernel/arch/gdt.cpp b/kernel/arch/gdt.c similarity index 95% rename from kernel/arch/gdt.cpp rename to kernel/arch/gdt.c index 1de5a0f..b9aef69 100644 --- a/kernel/arch/gdt.cpp +++ b/kernel/arch/gdt.c @@ -4,8 +4,6 @@ #include #include -extern "C" { - typedef struct __attribute__((packed)) { uint16_t limit; uint16_t base_16; @@ -56,6 +54,5 @@ void gdt_init( ) { set_gdt_entry(&gdt[10], 0, 0, 0, 0); gdt_load( ); - fb::printf("GDT инициализирован\n"); -} -} + fb_printf("GDT инициализирован\n"); +} \ No newline at end of file diff --git a/kernel/arch/idt.cpp b/kernel/arch/idt.c similarity index 79% rename from kernel/arch/idt.cpp rename to kernel/arch/idt.c index c211397..382cf89 100644 --- a/kernel/arch/idt.cpp +++ b/kernel/arch/idt.c @@ -4,7 +4,6 @@ #include #include -extern "C" { typedef struct __attribute__((packed)) { uint16_t limit; uint64_t base; @@ -101,24 +100,23 @@ static void encode_idt_entry(uint8_t vector, void *handler, uint8_t flags) { } static void exception_handler(struct frame state) { - fb::printf("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", - exception_names[state.int_number]); + 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); + 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"); } @@ -127,7 +125,7 @@ void isr_generic(struct frame state) { if (state.int_number < 32) { exception_handler(state); } else { - fb::printf("\nПрерывание! %u необработано :(\n", state.int_number); + fb_printf("\nПрерывание! %u необработано :(\n", state.int_number); } } @@ -145,10 +143,9 @@ void idt_init( ) { } idt_load( ); - fb::printf("IDT инициализирован\n"); + fb_printf("IDT инициализирован\n"); } void idt_set_ist(uint8_t vector, uint8_t ist) { idt[vector].ist = ist; } -} diff --git a/kernel/fb.cpp b/kernel/fb.c similarity index 84% rename from kernel/fb.cpp rename to kernel/fb.c index 26c9a4d..5f90130 100644 --- a/kernel/fb.cpp +++ b/kernel/fb.c @@ -1,150 +1,148 @@ -#include <6x8_slim_font.h> -#include -#include -#include -#include -#include -#include - -enum colors { - WHITE = 0xFFFFFF, - BLACK = 0x000000, - RED = 0xFF0000, - GREEN = 0x00FF00, - BLUE = 0x0000FF, - DARK_GREEN = 0x013220, -}; - -namespace fb { -static volatile struct limine_framebuffer_request framebuffer_request = { - .id = LIMINE_FRAMEBUFFER_REQUEST, - .revision = 0, - .response = (struct limine_framebuffer_response *)0 -}; - -struct limine_framebuffer_response *framebuffer_response; -struct limine_framebuffer *boot_framebuffer; - -uint32_t *fb_addr; -uint32_t text_color = GREEN; -uint32_t background = DARK_GREEN; -uint64_t width; -uint64_t height; -uint64_t pitch; -uint16_t bpp; - -size_t pos_x = 4; -size_t pos_y = 4; - -#define SCREEN_WIDTH width -#define SCREEN_HEIGHT height -#define SCREEN_BUFFER fb_addr - -void init( ) { - framebuffer_response = framebuffer_request.response; - boot_framebuffer = framebuffer_response->framebuffers[0]; - fb_addr = (uint32_t *)boot_framebuffer->address; - width = boot_framebuffer->width; - height = boot_framebuffer->height; - bpp = boot_framebuffer->bpp; - pitch = boot_framebuffer->pitch; - - for (uint64_t i = 0; i < width * height; i++) { fb_addr[i] = background; } - - fb::printf("0x%x %ux%u\n", fb_addr, width, height); -} - -void print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf) { - for (size_t j = 0; j < h; j++) { - for (size_t i = 0; i < w; i++) { - uint64_t where = (i + x) + (j + y) * width; - SCREEN_BUFFER[where] = buf[i + j * w]; - } - } -} - -static inline void print_bits(size_t x, size_t y, uint8_t num) { - for (size_t i = 0; i <= 7; i++) { - if ((num >> i) & 1) { - SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color; - } - } -} - -static inline uint32_t analyze(char glyth) { - return ((uint8_t)glyth - 32) * 8; -} - -static void print_char(int x, int y, char glyth) { - for (size_t i = 0; i < FONT_6X8_SLIM_CHAR_HEIGHT; i++) { - print_bits(x, y + i, font_6x8_slim[analyze(glyth) + i]); - } -} - -void scroll_fb( ) { - size_t last_line_index = - (SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH; - - for (size_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) { - for (size_t x = 0; x < SCREEN_WIDTH; x++) { - SCREEN_BUFFER[x + y * SCREEN_WIDTH] = - SCREEN_BUFFER[x + - (y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH]; - } - } - - for (size_t i = last_line_index; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++) { - SCREEN_BUFFER[i] = background; - } -} - -static void fb_putchar(char c) { - if (c == '\t') { - pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4; - } else if (c == '\n') { - // Новая строка - pos_x = 4; - pos_y += FONT_6X8_SLIM_CHAR_HEIGHT + 1; - } else { - if (pos_x >= SCREEN_WIDTH) { - pos_x = 4; - pos_y += FONT_6X8_SLIM_CHAR_HEIGHT + 1; - } - if (pos_y >= SCREEN_HEIGHT - FONT_6X8_SLIM_CHAR_HEIGHT) { - scroll_fb( ); - pos_y -= FONT_6X8_SLIM_CHAR_HEIGHT; - } - print_char(pos_x, pos_y, c); - pos_x += FONT_6X8_SLIM_CHAR_WIDTH; - } -} - -void printf(char *str, ...) { - va_list args; - va_start(args, str); - tool::format(&fb_putchar, str, args); - va_end(args); -} - -void printf_at(size_t x, size_t y, char *str, ...) { - va_list args; - va_start(args, str); - - // Сохраняем текущие значения pos_x и pos_y - size_t prev_pos_x = pos_x; - size_t prev_pos_y = pos_y; - - // Устанавливаем новые значения координат вывода - pos_x = x; - pos_y = y; - - // Выводим строку - tool::format(&fb_putchar, str, args); - - // Восстанавливаем предыдущие значения pos_x и pos_y - pos_x = prev_pos_x; - pos_y = prev_pos_y; - - va_end(args); -} -} // namespace fb \ No newline at end of file +#include <6x8_slim_font.h> +#include +#include +#include +#include +#include +#include + +enum colors { + WHITE = 0xFFFFFF, + BLACK = 0x000000, + RED = 0xFF0000, + GREEN = 0x00FF00, + BLUE = 0x0000FF, + DARK_GREEN = 0x013220, +}; + +static volatile struct limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST, + .revision = 0, + .response = (struct limine_framebuffer_response *)0 +}; + +static struct limine_framebuffer_response *framebuffer_response; +static struct limine_framebuffer *boot_framebuffer; + +uint32_t *fb_addr; +uint32_t text_color = GREEN; +uint32_t background = DARK_GREEN; +uint64_t width; +uint64_t height; +uint64_t pitch; +uint16_t bpp; + +size_t pos_x = 4; +size_t pos_y = 4; + +#define SCREEN_WIDTH width +#define SCREEN_HEIGHT height +#define SCREEN_BUFFER fb_addr + +void fb_init( ) { + framebuffer_response = framebuffer_request.response; + boot_framebuffer = framebuffer_response->framebuffers[0]; + fb_addr = (uint32_t *)boot_framebuffer->address; + width = boot_framebuffer->width; + height = boot_framebuffer->height; + bpp = boot_framebuffer->bpp; + pitch = boot_framebuffer->pitch; + + for (uint64_t i = 0; i < width * height; i++) { fb_addr[i] = background; } + + fb_printf("0x%x %ux%u\n", fb_addr, width, height); +} + +void fb_print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf) { + for (size_t j = 0; j < h; j++) { + for (size_t i = 0; i < w; i++) { + uint64_t where = (i + x) + (j + y) * width; + SCREEN_BUFFER[where] = buf[i + j * w]; + } + } +} + +static inline void print_bits(size_t x, size_t y, uint8_t num) { + for (size_t i = 0; i <= 7; i++) { + if ((num >> i) & 1) { + SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color; + } + } +} + +static inline uint32_t analyze(char glyth) { + return ((uint8_t)glyth - 32) * 8; +} + +static void print_char(int x, int y, char glyth) { + for (size_t i = 0; i < FONT_6X8_SLIM_CHAR_HEIGHT; i++) { + print_bits(x, y + i, font_6x8_slim[analyze(glyth) + i]); + } +} + +void scroll_fb( ) { + size_t last_line_index = + (SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH; + + for (size_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) { + for (size_t x = 0; x < SCREEN_WIDTH; x++) { + SCREEN_BUFFER[x + y * SCREEN_WIDTH] = + SCREEN_BUFFER[x + + (y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH]; + } + } + + for (size_t i = last_line_index; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++) { + SCREEN_BUFFER[i] = background; + } +} + +static void fb_putchar(char c) { + if (c == '\t') { + pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4; + } else if (c == '\n') { + // Новая строка + pos_x = 4; + pos_y += FONT_6X8_SLIM_CHAR_HEIGHT + 1; + } else { + if (pos_x >= SCREEN_WIDTH) { + pos_x = 4; + pos_y += FONT_6X8_SLIM_CHAR_HEIGHT + 1; + } + if (pos_y >= SCREEN_HEIGHT - FONT_6X8_SLIM_CHAR_HEIGHT) { + scroll_fb( ); + pos_y -= FONT_6X8_SLIM_CHAR_HEIGHT; + } + print_char(pos_x, pos_y, c); + pos_x += FONT_6X8_SLIM_CHAR_WIDTH; + } +} + +void fb_printf(char *str, ...) { + va_list args; + va_start(args, str); + tool_format(&fb_putchar, str, args); + va_end(args); +} + +void fb_printf_at(size_t x, size_t y, char *str, ...) { + va_list args; + va_start(args, str); + + // Сохраняем текущие значения pos_x и pos_y + size_t prev_pos_x = pos_x; + size_t prev_pos_y = pos_y; + + // Устанавливаем новые значения координат вывода + pos_x = x; + pos_y = y; + + // Выводим строку + tool_format(&fb_putchar, str, args); + + // Восстанавливаем предыдущие значения pos_x и pos_y + pos_x = prev_pos_x; + pos_y = prev_pos_y; + + va_end(args); +} \ No newline at end of file diff --git a/kernel/lock.cpp b/kernel/lock.c similarity index 60% rename from kernel/lock.cpp rename to kernel/lock.c index 8294f47..13ebb04 100644 --- a/kernel/lock.cpp +++ b/kernel/lock.c @@ -3,19 +3,18 @@ #include #include -namespace lock { -int swap(lock_t *lock) { +int lock_swap(lock_t *lock) { return __sync_bool_compare_and_swap(&lock->lock, 0, 1); } -void acquire(lock_t *lock) { +void lock_acquire(lock_t *lock) { uint64_t count = 0; for (;;) { - if (swap(lock)) { break; } + if (lock_swap(lock)) { break; } count++; if (count > 1000000) { - fb::printf("%s deadlock", lock->file); + fb_printf("%s блокировка зависла", lock->file); assert(0); } @@ -23,7 +22,6 @@ void acquire(lock_t *lock) { } } -void release(lock_t *lock) { +void lock_release(lock_t *lock) { __sync_bool_compare_and_swap(&lock->lock, 1, 0); -} -} // namespace lock \ No newline at end of file +} \ No newline at end of file diff --git a/kernel/main/main.cpp b/kernel/main/main.c similarity index 81% rename from kernel/main/main.cpp rename to kernel/main/main.c index d963476..1e8bc5b 100644 --- a/kernel/main/main.cpp +++ b/kernel/main/main.c @@ -3,7 +3,6 @@ #include extern void *bootpng_ptr; extern uint64_t bootpng_size; -extern "C" { typedef struct { unsigned char magic1; // must be zero @@ -28,10 +27,10 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { if (w < 1 || h < 1) return NULL; - data = (unsigned int *)mem::alloc((w * h + 2) * sizeof(unsigned int)); + data = (unsigned int *)mem_alloc((w * h + 2) * sizeof(unsigned int)); if (!data) { - fb::printf("Err %u, %x, %u kb\n", __LINE__, data, - ((w * h + 2) * sizeof(unsigned int)) / 1024); + fb_printf("Err %u, %x, %u kb\n", __LINE__, data, + ((w * h + 2) * sizeof(unsigned int)) / 1024); return NULL; } @@ -39,8 +38,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { case 1: if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) { - fb::printf("Err %u\n", __LINE__); - mem::free(data); + fb_printf("Err %u\n", __LINE__); + mem_free(data); return NULL; } for (y = i = 0; y < h; y++) { @@ -56,8 +55,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { case 2: if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) { - fb::printf("Err %u\n", __LINE__); - mem::free(data); + fb_printf("Err %u\n", __LINE__); + mem_free(data); return NULL; } for (y = i = 0; y < h; y++) { @@ -73,8 +72,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { case 9: if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) { - fb::printf("Err %u\n", __LINE__); - mem::free(data); + fb_printf("Err %u\n", __LINE__); + mem_free(data); return NULL; } y = i = 0; @@ -112,8 +111,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { case 10: if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) { - fb::printf("Err %u\n", __LINE__); - mem::free(data); + fb_printf("Err %u\n", __LINE__); + mem_free(data); return NULL; } y = i = 0; @@ -149,8 +148,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { } break; default: { - fb::printf("Err %u\n", __LINE__); - mem::free(data); + fb_printf("Err %u\n", __LINE__); + mem_free(data); return NULL; } } @@ -160,18 +159,17 @@ unsigned int *tga_parse(unsigned char *ptr, int size) { } void main( ) { for (uint64_t i = 512; i > 1; i--) { pause( ); } - fb::printf("Загрузка завершена! 1\n"); + fb_printf("Загрузка завершена! 1\n"); unsigned int *res = tga_parse((uint8_t *)bootpng_ptr, bootpng_size); - fb::printf("Загрузка завершена! 2 %x\n", res); + fb_printf("Загрузка завершена! 2 %x\n", res); tga_header_t *head = (tga_header_t *)bootpng_ptr; if (res != NULL) { - fb::printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]); + fb_printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]); } - fb::printf("Размер экрана загрузки: %ux%u \n", head->h, head->w); - mem::dump_memory( ); + fb_printf("Размер экрана загрузки: %ux%u \n", head->h, head->w); + mem_dump_memory( ); - fb::print_buf(0, 0, head->w, head->h, (uint32_t *)(res + 2)); -} + fb_print_buf(0, 0, head->w, head->h, (uint32_t *)(res + 2)); } \ No newline at end of file diff --git a/kernel/mem.cpp b/kernel/mem.c similarity index 69% rename from kernel/mem.cpp rename to kernel/mem.c index 7596d67..b6e346e 100644 --- a/kernel/mem.cpp +++ b/kernel/mem.c @@ -1,11 +1,10 @@ #include #include #include +#include +#include #include -#define BLOCK_SIZE 4096 -#define HHDM_OFFSET (hhdm_request.response->offset) - static volatile struct limine_memmap_request memmap_request = { .id = LIMINE_MEMMAP_REQUEST, .revision = 0, @@ -23,49 +22,48 @@ struct mem_entry { size_t size; uint8_t data[0]; }; + typedef struct mem_entry mem_entry_t; // Битовая карта для отслеживания занятых и свободных фреймов памяти -uint8_t *bitmap; +static uint8_t *bitmap; // Объем доступных блоков -uint64_t bitmap_available = 0; +static uint64_t bitmap_available = 0; // Объем блоков -uint64_t bitmap_limit = 0; +static uint64_t bitmap_limit = 0; // Верхняя граница доступной памяти -uint64_t limit; +static uint64_t limit; // Объем всего доступного физического адресного пространства -uint64_t usable = 0; +static uint64_t usable = 0; // Объем доступной виртуальной памяти -uint64_t available = 0; +static uint64_t available = 0; // Наивысший адрес в available space -uint64_t highest = 0; +static uint64_t highest = 0; // Количество записей в карте памяти -uint64_t mmmap_count = 0; +static uint64_t mmmap_count = 0; -const char memory_types[8][82] = { +static const char memory_types[8][82] = { "Доступно", "Зарезервировано", "ACPI, можно освободить", "ACPI NVS", "Плохая память", "Загрузчик, можно освободить", "Ядро и модули", "Буфер кадра" }; -struct limine_memmap_response *memmap_response; +static struct limine_memmap_response *memmap_response; static mem_entry_t *first_node; -namespace mem { - -void dump_memory( ) { +void mem_dump_memory( ) { mem_entry_t *curr = first_node; while (curr) { - fb::printf("->0x%x | %u.%u kb | %u | 0x%x\n", &curr->data, - (curr->size) / 1024, (curr->size) % 1024, curr->free, - curr->next); + fb_printf("->0x%x | %u.%u kb | %u | 0x%x\n", &curr->data, + (curr->size) / 1024, (curr->size) % 1024, curr->free, + curr->next); curr = curr->next; } } -void frame_free(void *addr, uint64_t frames) { +void mem_frame_free(void *addr, uint64_t frames) { // Проход по фреймам памяти и очистка битов в битовой карте uint64_t frame = (uint64_t)addr / BLOCK_SIZE; for (uint64_t i = frame; i < frames + frame; i++) { BIT_CLEAR(i); } @@ -73,7 +71,7 @@ void frame_free(void *addr, uint64_t frames) { } // Функция выделения памяти -void *frame_alloc(uint64_t wanted_frames) { +void *mem_frame_alloc(uint64_t wanted_frames) { void *addr; uint64_t available_frames = 0; @@ -97,13 +95,13 @@ void *frame_alloc(uint64_t wanted_frames) { return NULL; } -void *frame_calloc(uint64_t frames) { - void *addr = frame_alloc(frames); - tool::memset(addr + HHDM_OFFSET, 0, frames * BLOCK_SIZE); +void *mem_frame_calloc(uint64_t frames) { + void *addr = mem_frame_alloc(frames); + tool_memset(addr + HHDM_OFFSET, 0, frames * BLOCK_SIZE); return addr; } -void merge_blocks(mem_entry_t *start) { +static void merge_blocks(mem_entry_t *start) { if (!start->free) return; mem_entry_t *block = start; while (block->next && block->next->free) { @@ -112,7 +110,7 @@ void merge_blocks(mem_entry_t *start) { } } -void merge_all_blocks( ) { +void mem_merge_all_blocks( ) { mem_entry_t *curr = first_node; while (curr) { @@ -121,7 +119,7 @@ void merge_all_blocks( ) { } } -void add_block(void *addr, size_t size) { +static void add_block(void *addr, size_t size) { mem_entry_t *new_entry = (mem_entry_t *)addr; new_entry->size = size - sizeof(mem_entry_t); @@ -139,7 +137,7 @@ void add_block(void *addr, size_t size) { } } -void alloc_init(void *address, size_t length) { +static void alloc_init(void *address, size_t length) { first_node = (mem_entry_t *)address; first_node->size = length - sizeof(mem_entry_t); @@ -147,7 +145,7 @@ void alloc_init(void *address, size_t length) { first_node->next = NULL; } -void *alloc_align(size_t size, size_t alignment) { +static void *alloc_align(size_t size, size_t alignment) { mem_entry_t *curr = first_node; while (curr) { @@ -181,11 +179,11 @@ void *alloc_align(size_t size, size_t alignment) { return NULL; } -void *alloc(size_t size) { +void *mem_alloc(size_t size) { return alloc_align(size, 1); } -void free(void *addr) { +void mem_free(void *addr) { mem_entry_t *curr = first_node, *prev = NULL; while (curr != NULL) { if (curr->data == addr) { @@ -198,44 +196,44 @@ void free(void *addr) { } } -void *realloc(void *addr, size_t size) { +void *mem_realloc(void *addr, size_t size) { if (size == 0) { - free(addr); + mem_free(addr); return NULL; } - if (addr == NULL) { return alloc(size); } + if (addr == NULL) { return mem_alloc(size); } - void *new_addr = alloc(size); + void *new_addr = mem_alloc(size); if (new_addr == NULL) { return NULL; } - tool::memcpy(new_addr, addr, size); - free(addr); + tool_memcpy(new_addr, addr, size); + mem_free(addr); return new_addr; } // Инициализация менеджера памяти -void init( ) { +void mem_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); + 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, + // 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_FRAMEBUFFER) { - fb::printf("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u " - "килобайт\n", - mmaps[i]->length / 1024 / 1024, - (mmaps[i]->length / 1024) % 1024); + fb_printf("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u " + "килобайт\n", + mmaps[i]->length / 1024 / 1024, + (mmaps[i]->length / 1024) % 1024); } if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } @@ -253,7 +251,7 @@ void init( ) { if (mmaps[i]->length >= bitmap_size) { bitmap = (uint8_t *)mmaps[i]->base; - tool::memset(bitmap, 0xFF, bitmap_size); + tool_memset(bitmap, 0xFF, bitmap_size); mmaps[i]->length -= bitmap_size; mmaps[i]->base += bitmap_size; available -= bitmap_size; @@ -270,26 +268,24 @@ void init( ) { if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { - frame_free((void *)mmaps[i]->base + t, 1); + mem_frame_free((void *)mmaps[i]->base + t, 1); } } - fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); - fb::printf("Размер битовой карты: %u\n", bitmap_size); - alloc_init(frame_alloc(1), BLOCK_SIZE); + fb_printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); + fb_printf("Размер битовой карты: %u\n", bitmap_size); + alloc_init(mem_frame_alloc(1), BLOCK_SIZE); for (uint64_t i = 256 * 1024; i > 0; i -= BLOCK_SIZE) { - add_block(frame_alloc(1024), 1024 * BLOCK_SIZE); + add_block(mem_frame_alloc(1024), 1024 * BLOCK_SIZE); } - merge_all_blocks( ); - mem::dump_memory( ); - fb::printf("%u мегабайт выделено в динамичную память\n", - (256 * 1024 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024); - fb::printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", - (bitmap_available * BLOCK_SIZE) / 1024 / 1024, - available / 1024 / 1024); + mem_merge_all_blocks( ); + mem_dump_memory( ); + fb_printf("%u мегабайт выделено в динамичную память\n", + (256 * 1024 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024); + fb_printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", + (bitmap_available * BLOCK_SIZE) / 1024 / 1024, + available / 1024 / 1024); - fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); - fb::printf("Проверка менеджера памяти\n"); -} - -} // namespace mem \ No newline at end of file + fb_printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); + fb_printf("Проверка менеджера памяти\n"); +} \ No newline at end of file diff --git a/kernel/mod.c b/kernel/mod.c new file mode 100644 index 0000000..cb88d70 --- /dev/null +++ b/kernel/mod.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +// Структуры соответствующие ELF заголовкам +typedef struct { + unsigned char e_ident[16]; + uint16_t e_type; + uint16_t e_machine; + uint32_t e_version; + uint64_t e_entry; + uint64_t e_phoff; + uint64_t e_shoff; + uint32_t e_flags; + uint16_t e_ehsize; + uint16_t e_phentsize; + uint16_t e_phnum; + uint16_t e_shentsize; + uint16_t e_shnum; + uint16_t e_shstrndx; +} elf64_header_t; + +static env_t main_env; + +void *bootpng_ptr; +uint64_t bootpng_size; +void main( ); + +static void *elf_entry(void *module_bin, uint64_t size) { + // Приводим заголовок ELF файла к типу elf64_header_t + elf64_header_t *elf_header = (elf64_header_t *)module_bin; + + fb_printf(" Класс: ELF64\n"); + fb_printf(" Версия: %u\n", elf_header->e_ident[6]); + fb_printf(" ОС/ABI: %u\n", elf_header->e_ident[7]); + fb_printf(" Тип: %u\n", elf_header->e_type); + fb_printf(" Машина: %u\n", elf_header->e_machine); + fb_printf(" Версия: %u\n", elf_header->e_version); + fb_printf(" Точка входа: 0x%x\n", elf_header->e_entry); + + // Возвращаем указатель на точку входа + return (void *)((uint64_t)elf_header->e_entry + (uint64_t)module_bin); +} + +static volatile struct limine_module_request module_request = { + .id = LIMINE_MODULE_REQUEST, + .revision = 0, + .response = (struct limine_module_response *)0 +}; + +static struct limine_module_response *module_response; +static uint64_t modules_count = 0; + +void mod_init( ) { + main_env.fb_printf = &fb_printf; + module_response = module_request.response; + uint64_t module_count = module_response->module_count; + struct limine_file *module_ptr = (struct limine_file *)0; + + for (uint64_t i = 0; i < module_count; i++) { + module_ptr = module_response->modules[i]; + fb_printf("[%d] %s [%s] 0x%x\n", i, module_ptr->path, + module_ptr->cmdline, module_ptr->address); + fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", + module_ptr->size, module_ptr->media_type, + module_ptr->partition_index); + fb_printf("->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n", + module_ptr->mbr_disk_id, module_ptr->tftp_ip, + module_ptr->tftp_port); + + if (tool_starts_with(module_ptr->cmdline, "[BOOTIMG]")) { + fb_printf("\t\t[BOOTIMG]\n"); + bootpng_ptr = module_ptr->address; + bootpng_size = module_ptr->size; + continue; + } + if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; } + modules_count++; + module_info_t *(*module_init)(env_t * env) = + (module_info_t * (*)(env_t * env)) + elf_entry(module_ptr->address, module_ptr->size); + + fb_printf("\t->Точка входа: 0x%x\n", module_init); + + // module_info_t *ret = module_init(&main_env); + + // fb_printf("Инициализированно с кодом: %u\n", ret->err_code); + // fb_printf("Сообщение из модуля: %s\n\n", ret->message); + } + fb_printf("Модулей обработано: %u\n", modules_count); +} \ No newline at end of file diff --git a/kernel/mod.cpp b/kernel/mod.cpp deleted file mode 100644 index 277a78b..0000000 --- a/kernel/mod.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include -#include - -// Структуры соответствующие ELF заголовкам -typedef struct { - unsigned char e_ident[16]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - uint64_t e_entry; - uint64_t e_phoff; - uint64_t e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -} elf64_header_t; - -env_t main_env; - -extern "C" { -void *bootpng_ptr; -uint64_t bootpng_size; -void main( ); -} - -void *elf_entry(void *module_bin, uint64_t size) { - // Приводим заголовок ELF файла к типу elf64_header_t - elf64_header_t *elf_header = (elf64_header_t *)module_bin; - - fb::printf(" Класс: ELF64\n"); - fb::printf(" Версия: %u\n", elf_header->e_ident[6]); - fb::printf(" ОС/ABI: %u\n", elf_header->e_ident[7]); - fb::printf(" Тип: %u\n", elf_header->e_type); - fb::printf(" Машина: %u\n", elf_header->e_machine); - fb::printf(" Версия: %u\n", elf_header->e_version); - fb::printf(" Точка входа: 0x%x\n", elf_header->e_entry); -#if 0 - fb::printf(" Смещение таблицы программ: %u\n", elf_header->e_phoff); - fb::printf(" Смещение таблицы секций: %u\n", elf_header->e_shoff); - fb::printf(" Флаги: %u\n", elf_header->e_flags); - fb::printf(" Размер заголовка ELF файла: %u (байт)\n", - elf_header->e_ehsize); - fb::printf(" Размер записи таблицы программ: %u (байт)\n", - elf_header->e_phentsize); - fb::printf(" Количество записей таблицы программ: %u\n", - elf_header->e_phnum); - fb::printf(" Размер записи таблицы секций: %u (байт)\n", - elf_header->e_shentsize); - fb::printf(" Количество записей таблицы секций: %u\n", - elf_header->e_shnum); - fb::printf(" Индекс строки таблицы секций: %u\n", elf_header->e_shstrndx); -#endif - - // Возвращаем указатель на точку входа - return (void *)((uint64_t)elf_header->e_entry + (uint64_t)module_bin); -} - -namespace mod { -static volatile struct limine_module_request module_request = { - .id = LIMINE_MODULE_REQUEST, - .revision = 0, - .response = (struct limine_module_response *)0 -}; - -struct limine_module_response *module_response; -static uint64_t modules_count = 0; - -void init( ) { - main_env.fb_printf = &fb::printf; - module_response = module_request.response; - uint64_t module_count = module_response->module_count; - struct limine_file *module_ptr = (struct limine_file *)0; - - for (uint64_t i = 0; i < module_count; i++) { - module_ptr = module_response->modules[i]; - fb::printf("[%d] %s [%s] 0x%x\n", i, module_ptr->path, - module_ptr->cmdline, module_ptr->address); - fb::printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", - module_ptr->size, module_ptr->media_type, - module_ptr->partition_index); - fb::printf( - "->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n", - module_ptr->mbr_disk_id, module_ptr->tftp_ip, - module_ptr->tftp_port); - - if (tool::starts_with(module_ptr->cmdline, "[BOOTIMG]")) { - fb::printf("\t\t[BOOTIMG]\n"); - bootpng_ptr = module_ptr->address; - bootpng_size = module_ptr->size; - continue; - } - if (!tool::starts_with(module_ptr->cmdline, "[MOD]")) { continue; } - modules_count++; - module_info_t *(*module_init)(env_t * env) = - (module_info_t * (*)(env_t * env)) - elf_entry(module_ptr->address, module_ptr->size); - - fb::printf("\t->Точка входа: 0x%x\n", module_init); - - // module_info_t *ret = module_init(&main_env); - - // fb::printf("Инициализированно с кодом: %u\n", ret->err_code); - // fb::printf("Сообщение из модуля: %s\n\n", ret->message); - } - fb::printf("Модулей обработано: %u\n", modules_count); -} -} // namespace mod \ No newline at end of file diff --git a/kernel/start.c b/kernel/start.c new file mode 100644 index 0000000..c365a8a --- /dev/null +++ b/kernel/start.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include +#include + +// Точка входа +void _start( ) { + asm volatile("cli"); + + fb_init( ); + arch_init( ); + cpu_init( ); + mem_init( ); + mod_init( ); + fb_printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем " + "версии %u.%u.%u ***\n", + VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); + fb_printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__); + + for (;;) { asm volatile("hlt"); } +} \ No newline at end of file diff --git a/kernel/start.cpp b/kernel/start.cpp deleted file mode 100644 index 3c0b12a..0000000 --- a/kernel/start.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -// Точка входа -extern "C" void _start( ) { - asm volatile("cli"); - - fb::init( ); - arch::init( ); - cpu::init( ); - mem::init( ); - mod::init( ); - fb::printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем " - "версии %u.%u.%u ***\n", - VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); - fb::printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__); - - for (;;) { asm volatile("hlt"); } -} \ No newline at end of file diff --git a/kernel/sys.c b/kernel/sys.c new file mode 100644 index 0000000..44036d1 --- /dev/null +++ b/kernel/sys.c @@ -0,0 +1,30 @@ +#include +#include + +void sys_init( ) {} + +framebuffer_t *sys_alloc_framebuffer( ) { + return (framebuffer_t *)0; +} + +void sys_free_framebuffer(framebuffer_t *frame) {} + +void sys_exit(int code) {} + +int sys_get_error( ) { + return 0; +} + +sys_info_t *sys_get_info( ) {} + +module_info_t *sys_get_module(uid_t module_id) {} + +uid_t sys_new_thread(func_t func) {} + +int sys_delete_thread(uid_t thread_id) { + return 0; +} + +time_t sys_get_time( ) {} + +void sys_set_alarm(time_t time, func_t func) {} diff --git a/kernel/sys.cpp b/kernel/sys.cpp deleted file mode 100644 index 88fedf8..0000000 --- a/kernel/sys.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include - -namespace sys { -void init( ) {} - -framebuffer_t *alloc_framebuffer( ) { - return (framebuffer_t *)0; -} - -void free_framebuffer(framebuffer_t *frame) {} - -void exit(int code) {} - -int get_error( ) { - return 0; -} - -sys_info_t *get_info( ) { - return (sys_info_t *)0; -} - -module_info_t *get_module(uid_t module_id) { - return (module_info_t *)0; -} - -uid_t new_thread(func_t func) { - return { 0, 0, 0, 0 }; -} - -int delete_thread(uid_t thread_id) { - return 0; -} - -time_t get_time( ) { - return { 0, 0, 0, 0 }; -} - -void set_alarm(time_t time, func_t func) {} -} // namespace sys diff --git a/kernel/task.c b/kernel/task.c new file mode 100644 index 0000000..5b6e231 --- /dev/null +++ b/kernel/task.c @@ -0,0 +1,9 @@ + + +void task_new_thread( ) { + return; +} + +void task_delete_thread( ) { + return; +} \ No newline at end of file diff --git a/kernel/task.cpp b/kernel/task.cpp deleted file mode 100644 index 51bc326..0000000 --- a/kernel/task.cpp +++ /dev/null @@ -1,9 +0,0 @@ - - -void new_thread( ) { - return; -} - -void delete_thread( ) { - return; -} \ No newline at end of file diff --git a/kernel/tool.cpp b/kernel/tool.c similarity index 89% rename from kernel/tool.cpp rename to kernel/tool.c index 1421fff..d9c0e2e 100644 --- a/kernel/tool.cpp +++ b/kernel/tool.c @@ -1,174 +1,171 @@ -#include -#include -#include - -namespace tool { - -void memcpy(void *dest, void *src, uint64_t n) { - char *d = (char *)dest; - const char *s = (const char *)src; - - for (uint64_t i = 0; i < n; i++) { d[i] = s[i]; } -} - -void *memset(void *ptr, uint8_t n, uint64_t size) { - uint8_t *p = (uint8_t *)ptr; - for (uint64_t i = 0; i < size; i++) { p[i] = n; } - return ptr; -} - -uint64_t strlen(const char *str) { - uint64_t length = 0; - while (*str) { - length++; - str++; - } - return length; -} - -uint64_t starts_with(const char *str, const char *prefix) { - uint64_t str_len = strlen(str); - uint64_t prefix_len = strlen(prefix); - - if (prefix_len > str_len) { return 0; } - - for (uint64_t i = 0; i < prefix_len; i++) { - if (str[i] != prefix[i]) { return 0; } - } - - return 1; -} - -// Функция для форматированного вывода -void format(void (*putc)(char c), const char *format_string, va_list args) { - while (*format_string != '\0') { - if (*format_string == '%') { - format_string++; - if (*format_string == '\0') { - break; // Неожиданный конец строки формата - } - if (*format_string == '%') { - putc('%'); // Вывод одного символа '%' - } else if (*format_string == 'd') { - int64_t arg = va_arg(args, int64_t); - // Преобразование целочисленного аргумента в строку и вывод - // каждого символа - if (arg < 0) { - putc('-'); - arg = -arg; - } - if (arg == 0) { - putc('0'); - } else { - char buffer[10]; // Предполагаем, что максимальное число из - // 10 цифр - int64_t i = 0; - - while (arg > 0) { - buffer[i++] = '0' + (arg % 10); - arg /= 10; - } - - while (i > 0) { putc(buffer[--i]); } - } - } else if (*format_string == 's') { - const char *arg = va_arg(args, const char *); - // Вывод каждого символа строки - while (*arg != '\0') { - putc(*arg); - arg++; - } - } else if (*format_string == 'u') { - uint64_t arg = va_arg(args, uint64_t); - // Преобразование беззнакового целочисленного аргумента в строку - // и вывод каждого символа - if (arg == 0) { - putc('0'); - } else { - char buffer[32]; // Предполагаем, что максимальное число из - // 10 цифр - int64_t i = 0; - - while (arg > 0) { - buffer[i++] = '0' + (arg % 10); - arg /= 10; - } - - while (i > 0) { putc(buffer[--i]); } - } - } else if (*format_string == 'x') { - uint64_t arg = va_arg(args, uint64_t); - // Преобразование беззнакового целочисленного аргумента в - // шестнадцатеричную строку и вывод каждого символа - if (arg == 0) { - putc('0'); - } else { - char buffer[32]; // Предполагаем, что максимальное число из - // 8 символов - int64_t i = 0; - - while (arg > 0) { - int64_t rem = arg % 16; - if (rem < 10) { - buffer[i++] = '0' + rem; - } else { - buffer[i++] = 'A' + (rem - 10); - } - arg /= 16; - } - - while (i > 0) { putc(buffer[--i]); } - } - } else if (*format_string == 'c') { - char arg = va_arg(args, int); - // Вывод символа - putc(arg); - } else if (*format_string == 'o') { - uint64_t arg = va_arg(args, uint64_t); - // Преобразование беззнакового целочисленного аргумента в - // восьмеричную строку и вывод каждого символа - if (arg == 0) { - putc('0'); - } else { - char buffer[12]; // Предполагаем, что максимальное число из - // 11 символов - int64_t i = 0; - - while (arg > 0) { - buffer[i++] = '0' + (arg % 8); - arg /= 8; - } - - while (i > 0) { putc(buffer[--i]); } - } - } else if (*format_string == 'b') { - uint64_t arg = va_arg(args, uint64_t); - // Преобразование беззнакового целочисленного аргумента в - // двоичную строку и вывод каждого символа - if (arg == 0) { - putc('0'); - } else { - char buffer[33]; // Предполагаем, что максимальное число из - // 32 символа - int64_t i = 0; - - while (arg > 0) { - buffer[i++] = '0' + (arg % 2); - arg /= 2; - } - - while (i > 0) { putc(buffer[--i]); } - } - } else { - // Неподдерживаемый спецификатор формата - putc('?'); - } - } else { - putc(*format_string); - } - - format_string++; - } -} - -} // namespace tool \ No newline at end of file +#include +#include +#include + +void tool_memcpy(void *dest, void *src, uint64_t n) { + char *d = (char *)dest; + const char *s = (const char *)src; + + for (uint64_t i = 0; i < n; i++) { d[i] = s[i]; } +} + +void *tool_memset(void *ptr, uint8_t n, uint64_t size) { + uint8_t *p = (uint8_t *)ptr; + for (uint64_t i = 0; i < size; i++) { p[i] = n; } + return ptr; +} + +uint64_t tool_strlen(const char *str) { + uint64_t length = 0; + while (*str) { + length++; + str++; + } + return length; +} + +uint64_t tool_starts_with(const char *str, const char *prefix) { + uint64_t str_len = tool_strlen(str); + uint64_t prefix_len = tool_strlen(prefix); + + if (prefix_len > str_len) { return 0; } + + for (uint64_t i = 0; i < prefix_len; i++) { + if (str[i] != prefix[i]) { return 0; } + } + + return 1; +} + +// Функция для форматированного вывода +void tool_format(void (*putc)(char c), const char *format_string, + va_list args) { + while (*format_string != '\0') { + if (*format_string == '%') { + format_string++; + if (*format_string == '\0') { + break; // Неожиданный конец строки формата + } + if (*format_string == '%') { + putc('%'); // Вывод одного символа '%' + } else if (*format_string == 'd') { + int64_t arg = va_arg(args, int64_t); + // Преобразование целочисленного аргумента в строку и вывод + // каждого символа + if (arg < 0) { + putc('-'); + arg = -arg; + } + if (arg == 0) { + putc('0'); + } else { + char buffer[10]; // Предполагаем, что максимальное число из + // 10 цифр + int64_t i = 0; + + while (arg > 0) { + buffer[i++] = '0' + (arg % 10); + arg /= 10; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else if (*format_string == 's') { + const char *arg = va_arg(args, const char *); + // Вывод каждого символа строки + while (*arg != '\0') { + putc(*arg); + arg++; + } + } else if (*format_string == 'u') { + uint64_t arg = va_arg(args, uint64_t); + // Преобразование беззнакового целочисленного аргумента в строку + // и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[32]; // Предполагаем, что максимальное число из + // 10 цифр + int64_t i = 0; + + while (arg > 0) { + buffer[i++] = '0' + (arg % 10); + arg /= 10; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else if (*format_string == 'x') { + uint64_t arg = va_arg(args, uint64_t); + // Преобразование беззнакового целочисленного аргумента в + // шестнадцатеричную строку и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[32]; // Предполагаем, что максимальное число из + // 8 символов + int64_t i = 0; + + while (arg > 0) { + int64_t rem = arg % 16; + if (rem < 10) { + buffer[i++] = '0' + rem; + } else { + buffer[i++] = 'A' + (rem - 10); + } + arg /= 16; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else if (*format_string == 'c') { + char arg = va_arg(args, int); + // Вывод символа + putc(arg); + } else if (*format_string == 'o') { + uint64_t arg = va_arg(args, uint64_t); + // Преобразование беззнакового целочисленного аргумента в + // восьмеричную строку и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[12]; // Предполагаем, что максимальное число из + // 11 символов + int64_t i = 0; + + while (arg > 0) { + buffer[i++] = '0' + (arg % 8); + arg /= 8; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else if (*format_string == 'b') { + uint64_t arg = va_arg(args, uint64_t); + // Преобразование беззнакового целочисленного аргумента в + // двоичную строку и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[33]; // Предполагаем, что максимальное число из + // 32 символа + int64_t i = 0; + + while (arg > 0) { + buffer[i++] = '0' + (arg % 2); + arg /= 2; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else { + // Неподдерживаемый спецификатор формата + putc('?'); + } + } else { + putc(*format_string); + } + + format_string++; + } +} diff --git a/modules/com/main.cpp b/modules/com/main.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/pbuild.py b/pbuild.py index dafe261..f796ce1 100644 --- a/pbuild.py +++ b/pbuild.py @@ -56,7 +56,7 @@ def find_files(directory, extensions): def compile(file: str): - CC = "g++" if file.endswith('cpp') else "gcc" + CC = "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}" @@ -107,7 +107,7 @@ def check_tools(): def create_hdd(IMAGE_NAME): subprocess.run(["rm", "-f", IMAGE_NAME+".hdd"]) - subprocess.run(["dd", "if=/dev/zero", "bs=1M", "count=0", "seek=64", "of="+IMAGE_NAME+".hdd"]) + subprocess.run(["dd", "if=/dev/zero", "bs=1M", "count=0", "seek=4", "of="+IMAGE_NAME+".hdd"]) 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"]) diff --git a/templates/temp.c b/templates/temp.c new file mode 100644 index 0000000..532d27c --- /dev/null +++ b/templates/temp.c @@ -0,0 +1,12 @@ +/** + * <название файла>.c + * Краткое описание + * + * Полное описание + * + */ + +// Описание функции +void функция( ) { + Тело функции +} \ No newline at end of file diff --git a/templates/temp.h b/templates/temp.h new file mode 100644 index 0000000..c9a7a1c --- /dev/null +++ b/templates/temp.h @@ -0,0 +1,14 @@ +/** + * <название файла>.h + * Краткое описание + * + * Полное описание + * + */ + +#ifndef ИМЯ_ФАЙЛА_H +#define ИМЯ_ФАЙЛА_H + +void функция( ); + +#endif // <название файла>.h \ No newline at end of file