kinit.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include <asm/boot.h>
  2. #include <asm/port_io.h>
  3. #include <asm/sys.h>
  4. #include <assert.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/log.hpp>
  11. #include <kernel/mem.h>
  12. #include <kernel/process.hpp>
  13. #include <kernel/task.h>
  14. #include <kernel/tty.hpp>
  15. #include <kernel/vga.hpp>
  16. #include <stdint.h>
  17. #include <stdio.h>
  18. #include <types/bitmap.h>
  19. #include <types/status.h>
  20. #include <types/types.h>
  21. #define KERNEL_MAIN_BUF_SIZE (128)
  22. #define printkf(x...) \
  23. snprintf(buf, KERNEL_MAIN_BUF_SIZE, x); \
  24. console->print(buf)
  25. typedef void (*constructor)(void);
  26. extern constructor start_ctors;
  27. extern constructor end_ctors;
  28. void call_constructors_for_cpp(void)
  29. {
  30. for (constructor* ctor = &start_ctors; ctor != &end_ctors; ++ctor) {
  31. (*ctor)();
  32. }
  33. }
  34. static inline void save_loader_data(void)
  35. {
  36. memcpy(e820_mem_map, asm_e820_mem_map, sizeof(e820_mem_map));
  37. e820_mem_map_count = asm_e820_mem_map_count;
  38. e820_mem_map_entry_size = asm_e820_mem_map_entry_size;
  39. kernel_size = asm_kernel_size;
  40. memcpy(&mem_size_info, &asm_mem_size_info, sizeof(struct mem_size_info));
  41. }
  42. static inline void show_mem_info(char* buf)
  43. {
  44. uint32_t mem_size = 0;
  45. mem_size += 1024 * mem_size_info.n_1k_blks;
  46. mem_size += 64 * 1024 * mem_size_info.n_64k_blks;
  47. printkf(
  48. "Memory size: %d bytes (%d MB), 16k blocks: %d, 64k blocks: %d\n",
  49. mem_size,
  50. mem_size / 1024 / 1024,
  51. (int32_t)mem_size_info.n_1k_blks,
  52. (int32_t)mem_size_info.n_64k_blks);
  53. printkf(
  54. "mem_map_entry_count: %d , mem_map_entry_size: %d \n",
  55. e820_mem_map_count,
  56. e820_mem_map_entry_size);
  57. if (e820_mem_map_entry_size == 20) {
  58. struct e820_mem_map_entry_20* entry = (struct e820_mem_map_entry_20*)e820_mem_map;
  59. for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
  60. printkf(
  61. "[mem] entry %d: %llx ~ %llx, type: %d\n",
  62. i,
  63. entry->base,
  64. entry->base + entry->len,
  65. entry->type);
  66. }
  67. } else {
  68. struct e820_mem_map_entry_24* entry = (struct e820_mem_map_entry_24*)e820_mem_map;
  69. for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
  70. printkf(
  71. "[mem] entry %d: %lld ~ %lld, type: %d, acpi_attr: %d\n",
  72. i,
  73. entry->in.base,
  74. entry->in.base + entry->in.len,
  75. entry->in.type,
  76. entry->acpi_extension_attr);
  77. }
  78. }
  79. printkf("kernel size: %x\n", kernel_size);
  80. }
  81. void load_new_gdt(void)
  82. {
  83. create_segment_descriptor(gdt + 0, 0, 0, 0, 0);
  84. create_segment_descriptor(gdt + 1, 0, ~0, 0b1100, SD_TYPE_CODE_SYSTEM);
  85. create_segment_descriptor(gdt + 2, 0, ~0, 0b1100, SD_TYPE_DATA_SYSTEM);
  86. create_segment_descriptor(gdt + 3, 0, ~0, 0b1100, SD_TYPE_CODE_USER);
  87. create_segment_descriptor(gdt + 4, 0, ~0, 0b1100, SD_TYPE_DATA_USER);
  88. create_segment_descriptor(gdt + 5, (uint32_t)&tss, sizeof(tss), 0b0000, SD_TYPE_TSS);
  89. asm_load_gdt((6 * 8 - 1) << 16, (pptr_t)gdt);
  90. asm_load_tr((6 - 1) * 8);
  91. asm_cli();
  92. }
  93. void init_bss_section(void)
  94. {
  95. void* bss_addr = (void*)bss_section_start_addr;
  96. size_t bss_size = bss_section_end_addr - bss_section_start_addr;
  97. memset(bss_addr, 0x00, bss_size);
  98. }
  99. int init_console(const char* name)
  100. {
  101. if (name[0] == 't' && name[1] == 't' && name[2] == 'y') {
  102. if (name[3] == 'S' || name[3] == 's') {
  103. if (name[4] == '0') {
  104. console = types::_new<types::kernel_ident_allocator, serial_tty>(PORT_SERIAL0);
  105. return GB_OK;
  106. }
  107. if (name[4] == '1') {
  108. console = types::_new<types::kernel_ident_allocator, serial_tty>(PORT_SERIAL1);
  109. return GB_OK;
  110. }
  111. }
  112. if (name[3] == 'V' && name[3] == 'G' && name[3] == 'A') {
  113. console = types::_new<types::kernel_ident_allocator, vga_tty>();
  114. return GB_OK;
  115. }
  116. }
  117. return GB_FAILED;
  118. }
  119. extern void init_vfs();
  120. extern "C" uint32_t check_a20_on(void);
  121. extern "C" void NORETURN kernel_main(void)
  122. {
  123. int ret;
  124. ret = check_a20_on();
  125. assert(ret == 1);
  126. asm_enable_sse();
  127. init_bss_section();
  128. save_loader_data();
  129. load_new_gdt();
  130. // NOTE:
  131. // the initializer of c++ global objects MUST NOT contain
  132. // all kinds of memory allocations
  133. call_constructors_for_cpp();
  134. char buf[KERNEL_MAIN_BUF_SIZE] = { 0 };
  135. ret = init_serial_port(PORT_SERIAL0);
  136. assert(ret == GB_OK);
  137. init_idt();
  138. init_mem();
  139. init_pic();
  140. init_pit();
  141. ret = init_console("ttyS0");
  142. assert(ret == GB_OK);
  143. show_mem_info(buf);
  144. init_vfs();
  145. kmsg("switching execution to the scheduler...\n");
  146. init_scheduler();
  147. }