kernel_main.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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/stdio.h>
  12. #include <kernel/task.h>
  13. #include <kernel/tty.h>
  14. #include <kernel/vga.h>
  15. #include <types/assert.h>
  16. #include <types/bitmap.h>
  17. #include <types/status.h>
  18. #include <types/types.h>
  19. #define KERNEL_MAIN_BUF_SIZE (128)
  20. struct tty* console = NULL;
  21. #define printkf(x...) \
  22. snprintf(buf, KERNEL_MAIN_BUF_SIZE, x); \
  23. tty_print(console, buf)
  24. #define EVE_START(x) printkf(x "... ")
  25. #define INIT_START(x) EVE_START("initializing " x)
  26. #define INIT_OK() printkf("ok\n")
  27. #define INIT_FAILED() printkf("failed\n")
  28. typedef void (*constructor)(void);
  29. extern constructor start_ctors;
  30. extern constructor end_ctors;
  31. void call_constructors_for_cpp(void)
  32. {
  33. for (constructor* ctor = &start_ctors; ctor != &end_ctors; ++ctor) {
  34. (*ctor)();
  35. }
  36. }
  37. uint8_t e820_mem_map[1024];
  38. uint32_t e820_mem_map_count;
  39. uint32_t e820_mem_map_entry_size;
  40. size_t kernel_size;
  41. struct mem_size_info mem_size_info;
  42. static inline void save_loader_data(void)
  43. {
  44. memcpy(e820_mem_map, asm_e820_mem_map, sizeof(e820_mem_map));
  45. e820_mem_map_count = asm_e820_mem_map_count;
  46. e820_mem_map_entry_size = asm_e820_mem_map_entry_size;
  47. kernel_size = asm_kernel_size;
  48. memcpy(&mem_size_info, &asm_mem_size_info, sizeof(struct mem_size_info));
  49. }
  50. static inline void show_mem_info(char* buf)
  51. {
  52. uint32_t mem_size = 0;
  53. mem_size += 1024 * mem_size_info.n_1k_blks;
  54. mem_size += 64 * 1024 * mem_size_info.n_64k_blks;
  55. printkf(
  56. "Memory size: %d bytes (%d MB), 16k blocks: %d, 64k blocks: %d\n",
  57. mem_size,
  58. mem_size / 1024 / 1024,
  59. (int32_t)mem_size_info.n_1k_blks,
  60. (int32_t)mem_size_info.n_64k_blks);
  61. printkf(
  62. "mem_map_entry_count: %d , mem_map_entry_size: %d \n",
  63. e820_mem_map_count,
  64. e820_mem_map_entry_size);
  65. if (e820_mem_map_entry_size == 20) {
  66. struct e820_mem_map_entry_20* entry = (struct e820_mem_map_entry_20*)e820_mem_map;
  67. for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
  68. printkf(
  69. "[mem] entry %d: %llx ~ %llx, type: %d\n",
  70. i,
  71. entry->base,
  72. entry->base + entry->len,
  73. entry->type);
  74. }
  75. } else {
  76. struct e820_mem_map_entry_24* entry = (struct e820_mem_map_entry_24*)e820_mem_map;
  77. for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
  78. printkf(
  79. "[mem] entry %d: %lld ~ %lld, type: %d, acpi_attr: %d\n",
  80. i,
  81. entry->in.base,
  82. entry->in.base + entry->in.len,
  83. entry->in.type,
  84. entry->acpi_extension_attr);
  85. }
  86. }
  87. printkf("kernel size: %x\n", kernel_size);
  88. }
  89. static segment_descriptor new_gdt[6];
  90. struct tss32_t tss;
  91. void load_new_gdt(void)
  92. {
  93. create_segment_descriptor(new_gdt + 0, 0, 0, 0, 0);
  94. create_segment_descriptor(new_gdt + 1, 0, ~0, 0b1100, SD_TYPE_CODE_SYSTEM);
  95. create_segment_descriptor(new_gdt + 2, 0, ~0, 0b1100, SD_TYPE_DATA_SYSTEM);
  96. create_segment_descriptor(new_gdt + 3, 0, ~0, 0b1100, SD_TYPE_CODE_USER);
  97. create_segment_descriptor(new_gdt + 4, 0, ~0, 0b1100, SD_TYPE_DATA_USER);
  98. create_segment_descriptor(new_gdt + 5, (uint32_t)&tss, sizeof(tss), 0b0000, SD_TYPE_TSS);
  99. asm_load_gdt((6 * 8 - 1) << 16, (pptr_t)new_gdt);
  100. asm_load_tr((6 - 1) * 8);
  101. asm_cli();
  102. }
  103. void init_bss_section(void)
  104. {
  105. void* bss_addr = (void*)bss_section_start_addr;
  106. size_t bss_size = bss_section_end_addr - bss_section_start_addr;
  107. memset(bss_addr, 0x00, bss_size);
  108. }
  109. int init_console(const char* name)
  110. {
  111. console = ki_malloc(sizeof(struct tty));
  112. if (name[0] == 't' && name[1] == 't' && name[2] == 'y') {
  113. if (name[3] == 'S' || name[3] == 's') {
  114. if (name[4] == '0') {
  115. make_serial_tty(console, PORT_SERIAL0, 1);
  116. return GB_OK;
  117. }
  118. if (name[4] == '1') {
  119. make_serial_tty(console, PORT_SERIAL1, 1);
  120. return GB_OK;
  121. }
  122. }
  123. if (name[3] == 'V' && name[3] == 'G' && name[3] == 'A') {
  124. make_vga_tty(console);
  125. return GB_OK;
  126. }
  127. }
  128. ki_free(console);
  129. console = NULL;
  130. return GB_FAILED;
  131. }
  132. extern void init_vfs();
  133. extern void NORETURN init_scheduler();
  134. void NORETURN kernel_main(void)
  135. {
  136. assert(check_a20_on());
  137. asm_enable_sse();
  138. init_bss_section();
  139. save_loader_data();
  140. load_new_gdt();
  141. char buf[KERNEL_MAIN_BUF_SIZE] = { 0 };
  142. struct tty early_console;
  143. assert(init_serial_port(PORT_SERIAL0) == GB_OK);
  144. assert(make_serial_tty(&early_console, PORT_SERIAL0, 0) == GB_OK);
  145. console = &early_console;
  146. show_mem_info(buf);
  147. INIT_START("exception handlers");
  148. init_idt();
  149. INIT_OK();
  150. // NOTE:
  151. // the initializer of c++ global objects MUST NOT contain
  152. // all kinds of memory allocations
  153. INIT_START("C++ global objects");
  154. call_constructors_for_cpp();
  155. INIT_OK();
  156. INIT_START("memory allocation");
  157. init_mem();
  158. INIT_OK();
  159. INIT_START("programmable interrupt controller and timer");
  160. init_pic();
  161. init_pit();
  162. INIT_OK();
  163. printkf("Testing k_malloc...\n");
  164. char* k_malloc_buf = (char*)k_malloc(sizeof(char) * 4097);
  165. snprintf(k_malloc_buf, 4097, "This text is printed on the heap!\n");
  166. tty_print(console, k_malloc_buf);
  167. k_free(k_malloc_buf);
  168. assert(init_console("ttyS0") == GB_OK);
  169. init_vfs();
  170. printkf("switching execution to the scheduler...\n");
  171. init_scheduler(&tss);
  172. }
  173. void NORETURN __stack_chk_fail(void)
  174. {
  175. tty_print(console, "***** stack smashing detected! *****\n");
  176. for (;;)
  177. assert(0);
  178. }
  179. void crash(void)
  180. {
  181. asm volatile("ud2");
  182. }
  183. void _debugger_breakpoint(void)
  184. {
  185. #ifdef __BOCHS_SYSTEM__
  186. asm volatile("xchgw %%bx, %%bx");
  187. #else
  188. asm volatile("nop");
  189. #endif
  190. }