kernel_main.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include "kernel_main.h"
  2. #include <asm/boot.h>
  3. #include <asm/port_io.h>
  4. #include <asm/sys.h>
  5. #include <kernel/event/event.h>
  6. #include <kernel/hw/keyboard.h>
  7. #include <kernel/hw/serial.h>
  8. #include <kernel/hw/timer.h>
  9. #include <kernel/interrupt.h>
  10. #include <kernel/mem.h>
  11. #include <kernel/process.hpp>
  12. #include <kernel/stdio.h>
  13. #include <kernel/task.h>
  14. #include <kernel/tty.h>
  15. #include <kernel/vfs.h>
  16. #include <kernel/vga.h>
  17. #include <types/bitmap.h>
  18. #define KERNEL_MAIN_BUF_SIZE (128)
  19. struct tty* console = NULL;
  20. #define printkf(x...) \
  21. snprintf(buf, KERNEL_MAIN_BUF_SIZE, x); \
  22. tty_print(console, buf)
  23. #define EVE_START(x) printkf(x "... ")
  24. #define INIT_START(x) EVE_START("initializing " x)
  25. #define INIT_OK() printkf("ok\n")
  26. #define INIT_FAILED() printkf("failed\n")
  27. static inline void check_a20_status(void)
  28. {
  29. uint32_t result;
  30. result = check_a20_on();
  31. if (result) {
  32. tty_print(console, "a20 is on");
  33. } else {
  34. tty_print(console, "a20 is NOT on");
  35. }
  36. }
  37. static inline void halt_on_init_error(void)
  38. {
  39. MAKE_BREAK_POINT();
  40. asm_cli();
  41. while (1)
  42. asm_hlt();
  43. }
  44. typedef void (*constructor)(void);
  45. extern constructor start_ctors;
  46. extern constructor end_ctors;
  47. void call_constructors_for_cpp(void)
  48. {
  49. for (constructor* ctor = &start_ctors; ctor != &end_ctors; ++ctor) {
  50. (*ctor)();
  51. }
  52. }
  53. uint8_t e820_mem_map[1024];
  54. uint32_t e820_mem_map_count;
  55. uint32_t e820_mem_map_entry_size;
  56. size_t kernel_size;
  57. struct mem_size_info mem_size_info;
  58. static inline void save_loader_data(void)
  59. {
  60. memcpy(e820_mem_map, asm_e820_mem_map, sizeof(e820_mem_map));
  61. e820_mem_map_count = asm_e820_mem_map_count;
  62. e820_mem_map_entry_size = asm_e820_mem_map_entry_size;
  63. kernel_size = asm_kernel_size;
  64. memcpy(&mem_size_info, &asm_mem_size_info, sizeof(struct mem_size_info));
  65. }
  66. static inline void show_mem_info(char* buf)
  67. {
  68. uint32_t mem_size = 0;
  69. mem_size += 1024 * mem_size_info.n_1k_blks;
  70. mem_size += 64 * 1024 * mem_size_info.n_64k_blks;
  71. printkf(
  72. "Memory size: %d bytes (%d MB), 16k blocks: %d, 64k blocks: %d\n",
  73. mem_size,
  74. mem_size / 1024 / 1024,
  75. (int32_t)mem_size_info.n_1k_blks,
  76. (int32_t)mem_size_info.n_64k_blks);
  77. printkf(
  78. "mem_map_entry_count: %d , mem_map_entry_size: %d \n",
  79. e820_mem_map_count,
  80. e820_mem_map_entry_size);
  81. if (e820_mem_map_entry_size == 20) {
  82. struct e820_mem_map_entry_20* entry = (struct e820_mem_map_entry_20*)e820_mem_map;
  83. for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
  84. printkf(
  85. "[mem] entry %d: %llx ~ %llx, type: %d\n",
  86. i,
  87. entry->base,
  88. entry->base + entry->len,
  89. entry->type);
  90. }
  91. } else {
  92. struct e820_mem_map_entry_24* entry = (struct e820_mem_map_entry_24*)e820_mem_map;
  93. for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
  94. printkf(
  95. "[mem] entry %d: %lld ~ %lld, type: %d, acpi_attr: %d\n",
  96. i,
  97. entry->in.base,
  98. entry->in.base + entry->in.len,
  99. entry->in.type,
  100. entry->acpi_extension_attr);
  101. }
  102. }
  103. printkf("kernel size: %x\n", kernel_size);
  104. }
  105. static segment_descriptor new_gdt[6];
  106. struct tss32_t tss;
  107. void load_new_gdt(void)
  108. {
  109. create_segment_descriptor(new_gdt + 0, 0, 0, 0, 0);
  110. create_segment_descriptor(new_gdt + 1, 0, ~0, 0b1100, SD_TYPE_CODE_SYSTEM);
  111. create_segment_descriptor(new_gdt + 2, 0, ~0, 0b1100, SD_TYPE_DATA_SYSTEM);
  112. create_segment_descriptor(new_gdt + 3, 0, ~0, 0b1100, SD_TYPE_CODE_USER);
  113. create_segment_descriptor(new_gdt + 4, 0, ~0, 0b1100, SD_TYPE_DATA_USER);
  114. create_segment_descriptor(new_gdt + 5, (uint32_t)&tss, sizeof(tss), 0b0000, SD_TYPE_TSS);
  115. asm_load_gdt((6 * 8 - 1) << 16, (phys_ptr_t)new_gdt);
  116. asm_load_tr((6 - 1) * 8);
  117. asm_cli();
  118. }
  119. void init_bss_section(void)
  120. {
  121. void* bss_addr = (void*)bss_section_start_addr;
  122. size_t bss_size = bss_section_end_addr - bss_section_start_addr;
  123. memset(bss_addr, 0x00, bss_size);
  124. }
  125. static struct tty early_console;
  126. void NORETURN kernel_main(void)
  127. {
  128. // MAKE_BREAK_POINT();
  129. asm_enable_sse();
  130. init_bss_section();
  131. save_loader_data();
  132. load_new_gdt();
  133. char buf[KERNEL_MAIN_BUF_SIZE];
  134. init_serial_port(PORT_SERIAL0);
  135. if (make_serial_tty(&early_console, PORT_SERIAL0) != GB_OK) {
  136. halt_on_init_error();
  137. }
  138. console = &early_console;
  139. show_mem_info(buf);
  140. INIT_START("exception handlers");
  141. init_idt();
  142. INIT_OK();
  143. // NOTE:
  144. // the initializer of c++ global objects MUST NOT contain
  145. // all kinds of memory allocations
  146. INIT_START("C++ global objects");
  147. call_constructors_for_cpp();
  148. INIT_OK();
  149. INIT_START("memory allocation");
  150. init_mem();
  151. INIT_OK();
  152. INIT_START("programmable interrupt controller and timer");
  153. init_pic();
  154. init_pit();
  155. INIT_OK();
  156. printkf("Testing k_malloc...\n");
  157. char* k_malloc_buf = (char*)k_malloc(sizeof(char) * 4097);
  158. snprintf(k_malloc_buf, 4097, "This text is printed on the heap!\n");
  159. tty_print(console, k_malloc_buf);
  160. k_free(k_malloc_buf);
  161. k_malloc_buf[4096] = '\x89';
  162. init_vfs();
  163. struct inode* init = vfs_open("/init");
  164. vfs_read(init, buf, 128, 1, 10);
  165. printkf("switching execution to the scheduler...\n");
  166. init_scheduler(&tss);
  167. }