init.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "types.h"
  2. #include "VGA.h"
  3. #include "kmalloc.h"
  4. #include "i386.h"
  5. #include "i8253.h"
  6. #include "Keyboard.h"
  7. #include "Task.h"
  8. #include "system.h"
  9. #include "Disk.h"
  10. #include "PIC.h"
  11. #include "StdLib.h"
  12. #include "Syscall.h"
  13. #include "CMOS.h"
  14. #include "IDEDiskDevice.h"
  15. #include <VirtualFileSystem/NullDevice.h>
  16. #include <VirtualFileSystem/ZeroDevice.h>
  17. #include <VirtualFileSystem/FullDevice.h>
  18. #include <VirtualFileSystem/RandomDevice.h>
  19. #include <VirtualFileSystem/Ext2FileSystem.h>
  20. #include <VirtualFileSystem/VirtualFileSystem.h>
  21. #include <VirtualFileSystem/FileHandle.h>
  22. #include <AK/OwnPtr.h>
  23. #include "MemoryManager.h"
  24. #include <ELFLoader/ELFLoader.h>
  25. #include "Console.h"
  26. #include "ProcFileSystem.h"
  27. #include "RTC.h"
  28. #define TEST_VFS
  29. #define KSYMS
  30. //#define STRESS_TEST_SPAWNING
  31. //#define TEST_ELF_LOADER
  32. system_t system;
  33. void banner()
  34. {
  35. kprintf("\n");
  36. vga_set_attr(0x0a);
  37. kprintf(" _____ _ _ \n");
  38. vga_set_attr(0x0b);
  39. kprintf("| __|___ ___| |_ ___ ___| |_ \n");
  40. vga_set_attr(0x0c);
  41. kprintf("| | | -_| _| . | -_| _| _|\n");
  42. vga_set_attr(0x0d);
  43. kprintf("|_____|___|_| |___|___|_| |_| \n");
  44. vga_set_attr(0x07);
  45. kprintf("\n");
  46. }
  47. static byte parseHexDigit(char nibble)
  48. {
  49. if (nibble >= '0' && nibble <= '9')
  50. return nibble - '0';
  51. ASSERT(nibble >= 'a' && nibble <= 'f');
  52. return 10 + (nibble - 'a');
  53. }
  54. static Vector<KSym>* s_ksyms;
  55. Vector<KSym>& ksyms()
  56. {
  57. return *s_ksyms;
  58. }
  59. const KSym* ksymbolicate(dword address)
  60. {
  61. if (address < ksyms().first().address || address > ksyms().last().address)
  62. return nullptr;
  63. for (unsigned i = 0; i < ksyms().size(); ++i) {
  64. if (address < ksyms()[i + 1].address)
  65. return &ksyms()[i];
  66. }
  67. return nullptr;
  68. }
  69. static void loadKsyms(const ByteBuffer& buffer)
  70. {
  71. s_ksyms = new Vector<KSym>;
  72. auto* bufptr = (const char*)buffer.pointer();
  73. auto* startOfName = bufptr;
  74. dword address = 0;
  75. while (bufptr < buffer.endPointer()) {
  76. for (unsigned i = 0; i < 8; ++i)
  77. address = (address << 4) | parseHexDigit(*(bufptr++));
  78. bufptr += 3;
  79. startOfName = bufptr;
  80. while (*(++bufptr)) {
  81. if (*bufptr == '\n') {
  82. break;
  83. }
  84. }
  85. ksyms().append({ address, String(startOfName, bufptr - startOfName) });
  86. ++bufptr;
  87. }
  88. }
  89. static void undertaker_main() NORETURN;
  90. static void undertaker_main()
  91. {
  92. for (;;) {
  93. Task::doHouseKeeping();
  94. sleep(300);
  95. }
  96. }
  97. static void init_stage2() NORETURN;
  98. static void init_stage2()
  99. {
  100. kprintf("init stage2...\n");
  101. Syscall::initialize();
  102. auto keyboard = make<Keyboard>();
  103. Disk::initialize();
  104. #ifdef TEST_VFS
  105. auto vfs = make<VirtualFileSystem>();
  106. auto dev_zero = make<ZeroDevice>();
  107. vfs->registerCharacterDevice(1, 5, *dev_zero);
  108. auto dev_null = make<NullDevice>();
  109. vfs->registerCharacterDevice(1, 3, *dev_null);
  110. auto dev_full = make<FullDevice>();
  111. vfs->registerCharacterDevice(1, 7, *dev_full);
  112. auto dev_random = make<RandomDevice>();
  113. vfs->registerCharacterDevice(1, 8, *dev_random);
  114. vfs->registerCharacterDevice(85, 1, *keyboard);
  115. auto dev_hd0 = IDEDiskDevice::create();
  116. auto e2fs = Ext2FileSystem::create(dev_hd0.copyRef());
  117. e2fs->initialize();
  118. vfs->mountRoot(e2fs.copyRef());
  119. #ifdef KSYMS
  120. {
  121. auto handle = vfs->open("/kernel.map");
  122. if (!handle) {
  123. kprintf("Failed to open /kernel.map\n");
  124. } else {
  125. auto buffer = handle->readEntireFile();
  126. ASSERT(buffer);
  127. loadKsyms(buffer);
  128. }
  129. }
  130. #endif
  131. vfs->mount(ProcFileSystem::the(), "/proc");
  132. #endif
  133. #ifdef TEST_ELF_LOADER
  134. {
  135. auto testExecutable = vfs->open("/bin/id");
  136. ASSERT(testExecutable);
  137. auto testExecutableData = testExecutable->readEntireFile();
  138. ASSERT(testExecutableData);
  139. ExecSpace space;
  140. space.loadELF(move(testExecutableData));
  141. auto* elf_entry = space.symbolPtr("_start");
  142. ASSERT(elf_entry);
  143. typedef int (*MainFunctionPtr)(void);
  144. kprintf("elf_entry: %p\n", elf_entry);
  145. int rc = reinterpret_cast<MainFunctionPtr>(elf_entry)();
  146. kprintf("it returned %d\n", rc);
  147. }
  148. #endif
  149. #ifdef STRESS_TEST_SPAWNING
  150. dword lastAlloc = sum_alloc;
  151. for (unsigned i = 0; i < 100; ++i) {
  152. int error;
  153. auto* shTask = Task::createUserTask("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error);
  154. kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free);
  155. kprintf("sizeof(Task):%u\n", sizeof(Task));
  156. kprintf("delta:%u\n",sum_alloc - lastAlloc);
  157. lastAlloc = sum_alloc;
  158. sleep(600);
  159. }
  160. #endif
  161. int error;
  162. auto* shTask = Task::createUserTask("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error);
  163. banner();
  164. #if 0
  165. // It would be nice to exit this process, but right now it instantiates all kinds of things.
  166. // At the very least it needs to be made sure those things stick around as appropriate.
  167. DO_SYSCALL_A1(Syscall::PosixExit, 413);
  168. kprintf("uh, we're still going after calling sys$exit...\n");
  169. HANG;
  170. #endif
  171. for (;;) {
  172. //sleep(3600 * TICKS_PER_SECOND);
  173. asm("hlt");
  174. }
  175. }
  176. void init()
  177. {
  178. cli();
  179. kmalloc_init();
  180. vga_init();
  181. auto console = make<Console>();
  182. RTC::initialize();
  183. PIC::initialize();
  184. gdt_init();
  185. idt_init();
  186. MemoryManager::initialize();
  187. VirtualFileSystem::initializeGlobals();
  188. StringImpl::initializeGlobals();
  189. PIT::initialize();
  190. memset(&system, 0, sizeof(system));
  191. WORD base_memory = (CMOS::read(0x16) << 8) | CMOS::read(0x15);
  192. WORD ext_memory = (CMOS::read(0x18) << 8) | CMOS::read(0x17);
  193. kprintf("%u kB base memory\n", base_memory);
  194. kprintf("%u kB extended memory\n", ext_memory);
  195. auto procfs = ProcFileSystem::create();
  196. procfs->initialize();
  197. Task::initialize();
  198. Task::createKernelTask(undertaker_main, "undertaker");
  199. Task::createKernelTask(init_stage2, "init");
  200. scheduleNewTask();
  201. sti();
  202. // This now becomes the idle task :^)
  203. for (;;) {
  204. asm("hlt");
  205. }
  206. }