peredOS/kernel/kmain.c

205 lines
6.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 "heap.h"
#include "pmm.h"
#include "vmm.h"
#include "pic.h"
#include "logger.h"
#include "thread.h"
#include "string.h"
#include "multiboot.h"
extern uint32_t end; // Символ 'end' прописан в конце любого стандартного linker.ld
uint32_t kernel_end = (uint32_t)&end;
void test_thread() {
while(1) {
kprint_serial("YOOO! I am thread 2!\n");
kthread_yield();
}
}
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();
kprint_serial("--------------------\n");
log_info(LOG_NORMAL, "Enabling PMM...");
pmm_init(mbi, (uint32_t)&end);
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");
log_info(LOG_NORMAL, "Enabling VMM...");
vmm_init();
log_info(LOG_NORMAL, "Enabling KHeap...");
kheap_init();
kprint_serial("--- HEAP TESTING ---\n");
// Выделяем три разных куска памяти
int* arr1 = (int*)kmalloc(10 * sizeof(int));
char* str = (char*)kmalloc(64);
int* arr2 = (int*)kmalloc(5 * sizeof(int));
char hbuf[32];
kprint_serial("Allocated arr1 at virtual address: 0x");
itoa((uint32_t)arr1, hbuf, 16);
kprint_serial(hbuf);
kprint_serial("\n");
kprint_serial("Allocated str at virtual address: 0x");
itoa((uint32_t)str, hbuf, 16);
kprint_serial(hbuf);
kprint_serial("\n");
// Запишем туда данные, чтобы проверить, что маппинг страниц не падает при записи
arr1[0] = 1337;
str[0] = 'H';
str[1] = 'A';
str[2] = 'I';
str[3] = '\0';
kprint_serial("Data integrity check: str is ");
kprint_serial(str);
kprint_serial("\n");
// Освобождаем память обратно
kfree(arr1);
kfree(str);
kfree(arr2);
kprint_serial("Kfree done. It don't died twice!\n");
log_info(LOG_NORMAL, "Initializing threading...");
kthread_init();
log_info(LOG_NORMAL, "Creating test thread...");
kthread_create(test_thread);
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);
while (1) {
kprint_serial("HELLO! I am main thread 1!\n");
kthread_yield();
};
}