152 lines
5.2 KiB
C
152 lines
5.2 KiB
C
#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);
|
||
}
|