#include "../drivers/vga.h" #include "../drivers/serial.h" #include "../drivers/mouse.h" #include "../drivers/timer.h" #include "../drivers/speaker.h" #include "gdt.h" #include "idt.h" #include "pmm.h" #include "pic.h" #include "logger.h" #include "string.h" #include "multiboot.h" extern uint32_t end; // Символ 'end' прописан в конце любого стандартного linker.ld uint32_t kernel_end = (uint32_t)&end; void kernel_main(uint32_t magic, uint32_t mboot_addr) { log_info(LOG_NORMAL, "Initializing serial..."); serial_init(); if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { log_error(LOG_NORMAL, "fuck, i got invalid multiboot magic. IS THAT REALLY THE MULTIBOOT YOU TALKED ABOUT?"); while(1); } struct multiboot_info* mbi = (struct multiboot_info*)mboot_addr; if (!(mbi->flags & (1 << 6))) { log_error(LOG_NORMAL, "fuck, i haven't got a memory map. IS THAT REALLY THE MULTIBOOT YOU TALKED ABOUT?"); while(1); } log_info(LOG_NORMAL, "Initializing VGA..."); vga_init(); log_info(LOG_NORMAL, "Setting color white on black"); vga_set_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK); log_info(LOG_NORMAL, "Initializing GDT..."); gdt_init(); log_info(LOG_NORMAL, "Initializing IDT..."); idt_init(); log_info(LOG_NORMAL, "Remapping PIC..."); pic_remap(32, 40); log_info(LOG_NORMAL, "Unmasking IRQ 0... (timer)"); pic_clear_mask(0); log_info(LOG_NORMAL, "Unmasking IRQ 1... (keyboard)"); pic_clear_mask(1); log_info(LOG_NORMAL, "Unmasking IRQ 2... (slave pic)"); pic_clear_mask(2); log_info(LOG_NORMAL, "Unmasking IRQ 12... (mouse)"); pic_clear_mask(12); log_info(LOG_NORMAL, "Registering timer at 100Hz"); timer_init(100); log_info(LOG_NORMAL, "Registering mouse"); mouse_init(); log_info(LOG_NORMAL, "Enabling PMM..."); pmm_init(mbi, (uint32_t)&end); log_info(LOG_NORMAL, "Enabling IRQ..."); __asm__ __volatile__("sti"); vga_set_color(VGA_COLOR_LIGHT_GREEN, VGA_COLOR_BLACK); vga_print("h"); speaker_beep(100, 10); vga_print("a"); speaker_beep(125, 10); vga_print("i"); speaker_beep(150, 10); vga_print("!"); speaker_beep(175, 10); vga_print("!"); speaker_beep(200, 10); vga_print("!"); speaker_beep(225, 10); vga_print("!"); speaker_beep(250, 10); vga_print("!"); speaker_beep(275, 10); vga_print("!"); speaker_beep(300, 10); vga_print("!"); speaker_beep(325, 10); vga_print("\n # ### #### \n #### ### # ## ### #### # # # \n # # ##### ## ##### # # # # ### \n # # # # # # # # # # \n #### ### # ### #### ### #### \n # \n"); speaker_beep(350, 400); vga_init(); vga_set_color(VGA_COLOR_LIGHT_GRAY, VGA_COLOR_BLACK); kprint_serial("--- Memory Map From GRUB ---"); struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*)mbi->mmap_addr; while((uint32_t)mmap < mbi->mmap_addr + mbi->mmap_length) { char addr_buf[32]; char len_buf[32]; itoa((uint32_t)mmap->addr, addr_buf, 16); itoa((uint32_t)mmap->len, len_buf, 10); kprint_serial("Region: Base=0x"); kprint_serial(addr_buf); kprint_serial(" Size="); kprint_serial(len_buf); if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) { kprint_serial(" [FREE RAM]\n"); } else { kprint_serial(" [RESERVED]\n"); } // Переходим к следующей записи (учитываем поле size) mmap = (struct multiboot_mmap_entry*)((uint32_t)mmap + mmap->size + sizeof(mmap->size)); } kprint_serial("--- trying to allocate some fucking memory... ---\n"); kprint_serial("page 1... "); void* p1 = pmm_alloc_page(); kprint_serial("page 2..."); void* p2 = pmm_alloc_page(); kprint_serial("ok!"); char buf[32]; kprint_serial("PMM TEST: Page 1 allocated at 0x"); itoa((uint32_t)p1, buf, 16); kprint_serial(buf); kprint_serial("\n"); kprint_serial("PMM TEST: Page 2 allocated at 0x"); itoa((uint32_t)p2, buf, 16); kprint_serial(buf); kprint_serial("\n"); kprint_serial("freeing the pages back... page 1... "); pmm_free_page(p1); kprint_serial("page 2... "); pmm_free_page(p2); kprint_serial("it don't died!\n"); kprint_serial("\n--- PMM MEMORY STATS ---\n"); pmm_get_stats(); // Просто запускаем сбор, она запишет всё в глобальную переменную // Берем указатель на глобальную переменную pmm_stats_t* my_stats = pmm_get_stats_ptr(); kprint_serial("Total Memory: "); itoa(my_stats->total_memory >> 20, buf, 10); kprint_serial(buf); kprint_serial(" MB\n"); kprint_serial("Used Memory: "); itoa(my_stats->used_memory >> 10, buf, 10); kprint_serial(buf); kprint_serial(" KB\n"); kprint_serial("Free Memory: "); itoa(my_stats->free_memory >> 20, buf, 10); kprint_serial(buf); kprint_serial(" MB\n"); kprint_serial("------------------------\n\n"); while (1); }