diff --git a/.gitignore b/.gitignore index 41abf31..44423cc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ mseos.iso bin/ limine/ ovmf/ +modules/helloworld/helloworld.elf +modules/com/com.elf diff --git a/build.py b/build.py index 5c87262..64f6dbe 100644 --- a/build.py +++ b/build.py @@ -7,7 +7,7 @@ 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 = "-Wall -Wextra" +WARN_FLAGS = "-w -Wall -Wextra" 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" @@ -71,7 +71,23 @@ def check_tools(): subprocess.run(["sudo", "apt", "install"] + missing_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(["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(["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"]) + + def create_iso(IMAGE_NAME): + subprocess.run(["rm", "-f", IMAGE_NAME+".iso"]) subprocess.run(["rm", "-rf", "iso_root"]) subprocess.run(["mkdir", "-p", "iso_root"]) subprocess.run(["cp", "-v", "iso_root/"]) @@ -80,6 +96,9 @@ def create_iso(IMAGE_NAME): "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(["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/"]) subprocess.run(["cp", "-v", "limine/BOOTIA32.EFI", "iso_root/EFI/BOOT/"]) subprocess.run(["xorriso", "-as", "mkisofs", "-b", "limine-bios-cd.bin", @@ -90,20 +109,8 @@ def create_iso(IMAGE_NAME): subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".iso"]) subprocess.run(["rm", "-rf", "iso_root"]) -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(["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", "::/EFI", "::/EFI/BOOT"]) - 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", - "limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"]) - - 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""") subprocess.run(["rm", "-rf", "bin"]) subprocess.run(["mkdir", "-p", "bin"]) @@ -116,7 +123,7 @@ if __name__ == "__main__": check_limine() check_tools() compile_all() - create_hdd("mseos") create_iso("mseos") + create_hdd("mseos") print("qemu-system-x86_64 -M q35 -m 8G -smp 8 -bios ovmf/OVMF.fd -hda mseos.hdd") \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..806b3b7 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +#!/bin/sh +python3 build.py \ No newline at end of file diff --git a/configs/limine.cfg b/configs/limine.cfg index 5b1c74a..c905664 100644 --- a/configs/limine.cfg +++ b/configs/limine.cfg @@ -10,3 +10,11 @@ INTERFACE_BRANDING=By Aren Elchinyan 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 diff --git a/include/arch.h b/include/arch.h index bf31e64..1588660 100644 --- a/include/arch.h +++ b/include/arch.h @@ -1,3 +1,3 @@ namespace arch { - void init(); +void init( ); } \ No newline at end of file diff --git a/include/cpu.h b/include/cpu.h index 561ee00..e9ecad4 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,3 +1,3 @@ namespace cpu { - void init(); +void init( ); } \ No newline at end of file diff --git a/include/fb.h b/include/fb.h index cb8d119..6a80155 100644 --- a/include/fb.h +++ b/include/fb.h @@ -1,3 +1,12 @@ +#include +#include +#include + namespace fb { - void init(); -} \ No newline at end of file + +void init( ); + +void printf(char *str, ...); + +void printf_at(size_t x, size_t y, char *str, ...); +} // namespace fb \ No newline at end of file diff --git a/include/lock.h b/include/lock.h new file mode 100644 index 0000000..9407502 --- /dev/null +++ b/include/lock.h @@ -0,0 +1,15 @@ +#include + +typedef struct { + int lock; + const char* file; +} lock_t; + +#define LOCK_INIT \ + (lock_t) { 0, __FILE__ } + +namespace lock { +int swap(lock_t* lock); +void acquire(lock_t* lock); +void release(lock_t* lock); +} // namespace lock diff --git a/include/mem.h b/include/mem.h new file mode 100644 index 0000000..5c3edcb --- /dev/null +++ b/include/mem.h @@ -0,0 +1,5 @@ +namespace mem { +void init( ); +void *alloc_block( ); +void free_block(void *block); +} // namespace mem \ No newline at end of file diff --git a/include/mod.h b/include/mod.h new file mode 100644 index 0000000..b8823a1 --- /dev/null +++ b/include/mod.h @@ -0,0 +1,3 @@ +namespace mod { +void init( ); +} \ No newline at end of file diff --git a/include/tool.h b/include/tool.h index 9461a88..f1f04bb 100644 --- a/include/tool.h +++ b/include/tool.h @@ -1,6 +1,25 @@ #include +#define assert(check) \ + ({ \ + if (!(check)) { \ + fb::printf("\nassert() failed in %s() (%s:%d)\n", __func__, \ + __FILE__, __LINE__); \ + for (;;) asm volatile("hlt"); \ + } \ + }) + +#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))) + +#define BIT_SET(BIT) (bitmap[(BIT) / 8] |= (1 << ((BIT) % 8))) +#define BIT_CLEAR(BIT) (bitmap[(BIT) / 8] &= ~(1 << ((BIT) % 8))) +#define BIT_GET(BIT) ((bitmap[(BIT) / 8] >> ((BIT) % 8)) & 1) namespace tool { - void format(void (*putc)(char c), const char *format_string, va_list args); -} \ No newline at end of file +void memcpy(void *dest, void *src, uint64_t n); +void *memset(void *ptr, uint8_t n, uint64_t size); +void format(void (*putc)(char c), const char *format_string, va_list args); +} // namespace tool \ No newline at end of file diff --git a/kernel/arch.cpp b/kernel/arch.cpp index 3d5d2e0..f9850fe 100644 --- a/kernel/arch.cpp +++ b/kernel/arch.cpp @@ -1,17 +1,15 @@ #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; +static volatile struct limine_kernel_address_request kernel_address_request = { + .id = LIMINE_KERNEL_ADDRESS_REQUEST, + .revision = 0, + .response = (struct limine_kernel_address_response *)0 +}; - void init() { - kernel_address_response = kernel_address_request.response; - } -} \ No newline at end of file +struct limine_kernel_address_response *kernel_address_response; + +void init( ) { + kernel_address_response = kernel_address_request.response; +} +} // namespace arch \ No newline at end of file diff --git a/kernel/cpu.cpp b/kernel/cpu.cpp index fec6bcd..e7c78e7 100644 --- a/kernel/cpu.cpp +++ b/kernel/cpu.cpp @@ -1,15 +1,168 @@ -#include +#include #include - +#include +#include namespace cpu { - static bool x87_support = false; - static bool sse_support = false; - static bool avx_support = false; +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 init() { - x87_support = false; - sse_support = false; - avx_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( ); +} +} // namespace cpu \ No newline at end of file diff --git a/kernel/fb.cpp b/kernel/fb.cpp index 7196e12..d41d741 100644 --- a/kernel/fb.cpp +++ b/kernel/fb.cpp @@ -1,32 +1,137 @@ +#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 - }; +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; - uint64_t width; - uint64_t height; - uint64_t pitch; - uint16_t bpp; - - 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; +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; - for (uint64_t i = 0; i < width * height; i++) { - fb_addr[i] = 0x0000FF; - } - } -} \ No newline at end of file +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; + + for (uint64_t i = 0; i < width * height; i++) { fb_addr[i] = background; } +} + +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 diff --git a/kernel/lock.cpp b/kernel/lock.cpp new file mode 100644 index 0000000..8294f47 --- /dev/null +++ b/kernel/lock.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +namespace lock { +int swap(lock_t *lock) { + return __sync_bool_compare_and_swap(&lock->lock, 0, 1); +} + +void acquire(lock_t *lock) { + uint64_t count = 0; + + for (;;) { + if (swap(lock)) { break; } + count++; + if (count > 1000000) { + fb::printf("%s deadlock", lock->file); + assert(0); + } + + asm volatile("pause"); + } +} + +void release(lock_t *lock) { + __sync_bool_compare_and_swap(&lock->lock, 1, 0); +} +} // namespace lock \ No newline at end of file diff --git a/kernel/mem.cpp b/kernel/mem.cpp index e69de29..2533aa8 100644 --- a/kernel/mem.cpp +++ b/kernel/mem.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#define BLOCK_SIZE 4096 +static volatile struct limine_memmap_request memmap_request = { + .id = LIMINE_MEMMAP_REQUEST, + .revision = 0, + .response = (struct limine_memmap_response *)0 +}; +static volatile struct limine_hhdm_request hhdm_request = { + .id = LIMINE_HHDM_REQUEST, + .revision = 0, + .response = (struct limine_hhdm_response *)0 +}; + +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 limit; +uint64_t usable = 0; +uint64_t available = 0; +uint64_t highest = 0; +uint64_t mmmap_count = 0; + +lock_t lock = LOCK_INIT; + +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) {} + +void *malloc(uint64_t count) { + return NULL; +} + +void *calloc(uint64_t frames) { + return (void *)0; +} + +void *alloc(uint64_t size) { + return (void *)0; +} +} // namespace mem \ No newline at end of file diff --git a/kernel/mod.cpp b/kernel/mod.cpp new file mode 100644 index 0000000..c067aaa --- /dev/null +++ b/kernel/mod.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +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 module_count = 0; + +void init( ) { + module_response = module_request.response; + 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("->Size: %u, media_type: %u, partition_index: %u\n", + module_ptr->size, module_ptr->media_type, + module_ptr->partition_index); + fb::printf("->mbr_disk_id: %u, tftp_ip: %u, tftp_port: %u\n\n", + module_ptr->mbr_disk_id, module_ptr->tftp_ip, + module_ptr->tftp_port); + } +} +} // namespace mod \ No newline at end of file diff --git a/kernel/start.cpp b/kernel/start.cpp index f54db67..f6c5a93 100644 --- a/kernel/start.cpp +++ b/kernel/start.cpp @@ -1,20 +1,19 @@ -#include #include #include #include +#include +#include +#include #include - - // Точка входа -extern "C" void _start() { - asm volatile("cli"); +extern "C" void _start( ) { + asm volatile("cli"); - arch::init(); - cpu::init(); - fb::init(); + fb::init( ); + fb::printf("Привет, мир!!\n"); + cpu::init( ); + mem::init( ); - for (;;) { - asm volatile("hlt"); - } + for (;;) { asm volatile("hlt"); } } \ No newline at end of file diff --git a/kernel/tool.cpp b/kernel/tool.cpp index 9f69e95..c798d20 100644 --- a/kernel/tool.cpp +++ b/kernel/tool.cpp @@ -3,54 +3,150 @@ #include namespace tool { - // Функция для форматированного вывода - 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') { - int arg = va_arg(args, int); - // Преобразование целочисленного аргумента в строку и вывод каждого символа - if (arg < 0) { - putc('-'); - arg = -arg; - } - if (arg == 0) { - putc('0'); - } else { - char buffer[10]; // Предполагаем, что максимальное число из 10 цифр - int i = 0; - while (arg > 0) { - buffer[i++] = '0' + (arg % 10); - arg /= 10; - } +void memcpy(void *dest, void *src, uint64_t n) { + char *d = (char *)dest; + const char *s = (const char *)src; - 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 { - // Неподдерживаемый спецификатор формата - putc('?'); - } - } else { - putc(*format_string); - } + for (uint64_t i = 0; i < n; i++) { d[i] = s[i]; } +} - format_string++; - } - } -} \ No newline at end of file +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; +} + +// Функция для форматированного вывода +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') { + int arg = va_arg(args, int); + // Преобразование целочисленного аргумента в строку и вывод + // каждого символа + if (arg < 0) { + putc('-'); + arg = -arg; + } + if (arg == 0) { + putc('0'); + } else { + char buffer[10]; // Предполагаем, что максимальное число из + // 10 цифр + int 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') { + unsigned int arg = va_arg(args, unsigned int); + // Преобразование беззнакового целочисленного аргумента в строку + // и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[10]; // Предполагаем, что максимальное число из + // 10 цифр + int i = 0; + + while (arg > 0) { + buffer[i++] = '0' + (arg % 10); + arg /= 10; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else if (*format_string == 'x') { + unsigned int arg = va_arg(args, unsigned int); + // Преобразование беззнакового целочисленного аргумента в + // шестнадцатеричную строку и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[9]; // Предполагаем, что максимальное число из 8 + // символов + int i = 0; + + while (arg > 0) { + int 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') { + unsigned int arg = va_arg(args, unsigned int); + // Преобразование беззнакового целочисленного аргумента в + // восьмеричную строку и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[12]; // Предполагаем, что максимальное число из + // 11 символов + int i = 0; + + while (arg > 0) { + buffer[i++] = '0' + (arg % 8); + arg /= 8; + } + + while (i > 0) { putc(buffer[--i]); } + } + } else if (*format_string == 'b') { + unsigned int arg = va_arg(args, unsigned int); + // Преобразование беззнакового целочисленного аргумента в + // двоичную строку и вывод каждого символа + if (arg == 0) { + putc('0'); + } else { + char buffer[33]; // Предполагаем, что максимальное число из + // 32 символа + int 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 diff --git a/modules/com/main.cpp b/modules/com/main.cpp new file mode 100644 index 0000000..e69de29 diff --git a/modules/helloworld/main.cpp b/modules/helloworld/main.cpp new file mode 100644 index 0000000..e69de29