init.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <AK/Types.h>
  2. #include "kmalloc.h"
  3. #include "i386.h"
  4. #include "i8253.h"
  5. #include <Kernel/Devices/KeyboardDevice.h>
  6. #include "Process.h"
  7. #include "PIC.h"
  8. #include <Kernel/Devices/IDEDiskDevice.h>
  9. #include <Kernel/Devices/MBRPartitionTable.h>
  10. #include <Kernel/Devices/DiskPartition.h>
  11. #include "KSyms.h"
  12. #include <Kernel/Devices/NullDevice.h>
  13. #include <Kernel/Devices/ZeroDevice.h>
  14. #include <Kernel/Devices/FullDevice.h>
  15. #include <Kernel/Devices/RandomDevice.h>
  16. #include <Kernel/FileSystem/Ext2FileSystem.h>
  17. #include <Kernel/FileSystem/VirtualFileSystem.h>
  18. #include <Kernel/VM/MemoryManager.h>
  19. #include <Kernel/FileSystem/ProcFS.h>
  20. #include "RTC.h"
  21. #include <Kernel/TTY/VirtualConsole.h>
  22. #include "Scheduler.h"
  23. #include <Kernel/Devices/PS2MouseDevice.h>
  24. #include <Kernel/TTY/PTYMultiplexer.h>
  25. #include <Kernel/FileSystem/DevPtsFS.h>
  26. #include <Kernel/Devices/BXVGADevice.h>
  27. #include <Kernel/Net/E1000NetworkAdapter.h>
  28. #include <Kernel/Net/NetworkTask.h>
  29. #include <Kernel/Devices/DebugLogDevice.h>
  30. #include <Kernel/Multiboot.h>
  31. #include <Kernel/KParams.h>
  32. //#define STRESS_TEST_SPAWNING
  33. VirtualConsole* tty0;
  34. VirtualConsole* tty1;
  35. VirtualConsole* tty2;
  36. VirtualConsole* tty3;
  37. KeyboardDevice* keyboard;
  38. PS2MouseDevice* ps2mouse;
  39. DebugLogDevice* dev_debuglog;
  40. NullDevice* dev_null;
  41. VFS* vfs;
  42. #ifdef STRESS_TEST_SPAWNING
  43. [[noreturn]] static void spawn_stress()
  44. {
  45. dword last_sum_alloc = sum_alloc;
  46. for (unsigned i = 0; i < 10000; ++i) {
  47. int error;
  48. Process::create_user_process("/bin/true", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0);
  49. dbgprintf("malloc stats: alloc:%u free:%u eternal:%u !delta:%u\n", sum_alloc, sum_free, kmalloc_sum_eternal, sum_alloc - last_sum_alloc);
  50. last_sum_alloc = sum_alloc;
  51. sleep(60);
  52. }
  53. for (;;) {
  54. asm volatile("hlt");
  55. }
  56. }
  57. #endif
  58. [[noreturn]] static void init_stage2()
  59. {
  60. Syscall::initialize();
  61. auto dev_zero = make<ZeroDevice>();
  62. auto dev_full = make<FullDevice>();
  63. auto dev_random = make<RandomDevice>();
  64. auto dev_ptmx = make<PTYMultiplexer>();
  65. // TODO: decide what drive/partition to use based on cmdline from
  66. // bootloader. currently hardcoded to the equivalent of hd0,1.
  67. auto dev_hd0 = IDEDiskDevice::create();
  68. MBRPartitionTable dev_hd0pt(dev_hd0.copy_ref());
  69. if (!dev_hd0pt.initialize()) {
  70. kprintf("init_stage2: couldn't read MBR from disk");
  71. hang();
  72. }
  73. auto dev_hd0p1 = dev_hd0pt.partition(1);
  74. if (!dev_hd0p1) {
  75. kprintf("init_stage2: couldn't get first partition");
  76. hang();
  77. }
  78. auto e2fs = Ext2FS::create(*dev_hd0p1.copy_ref());
  79. if (!e2fs->initialize()) {
  80. kprintf("init_stage2: couldn't open root filesystem");
  81. hang();
  82. }
  83. vfs->mount_root(e2fs.copy_ref());
  84. dbgprintf("Load ksyms\n");
  85. load_ksyms();
  86. dbgprintf("Loaded ksyms\n");
  87. vfs->mount(ProcFS::the(), "/proc");
  88. vfs->mount(DevPtsFS::the(), "/dev/pts");
  89. int error;
  90. auto* system_server_process = Process::create_user_process("/bin/SystemServer", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0);
  91. if (error != 0) {
  92. dbgprintf("init_stage2: error spawning SystemServer: %d\n", error);
  93. hang();
  94. }
  95. system_server_process->set_priority(Process::HighPriority);
  96. #ifdef STRESS_TEST_SPAWNING
  97. Process::create_kernel_process("spawn_stress", spawn_stress);
  98. #endif
  99. current->process().sys$exit(0);
  100. ASSERT_NOT_REACHED();
  101. }
  102. extern "C" {
  103. multiboot_info_t* multiboot_info_ptr;
  104. }
  105. extern "C" [[noreturn]] void init()
  106. {
  107. sse_init();
  108. kmalloc_init();
  109. init_ksyms();
  110. // must come after kmalloc_init because we use AK_MAKE_ETERNAL in KParams
  111. new KParams(String(reinterpret_cast<const char*>(multiboot_info_ptr->cmdline)));
  112. vfs = new VFS;
  113. dev_debuglog = new DebugLogDevice;
  114. auto console = make<Console>();
  115. RTC::initialize();
  116. PIC::initialize();
  117. gdt_init();
  118. idt_init();
  119. keyboard = new KeyboardDevice;
  120. ps2mouse = new PS2MouseDevice;
  121. dev_null = new NullDevice;
  122. VirtualConsole::initialize();
  123. tty0 = new VirtualConsole(0, VirtualConsole::AdoptCurrentVGABuffer);
  124. tty1 = new VirtualConsole(1);
  125. tty2 = new VirtualConsole(2);
  126. tty3 = new VirtualConsole(3);
  127. VirtualConsole::switch_to(0);
  128. kprintf("Starting Serenity Operating System...\n");
  129. MemoryManager::initialize();
  130. PIT::initialize();
  131. new BXVGADevice;
  132. auto e1000 = E1000NetworkAdapter::autodetect();
  133. Retained<ProcFS> new_procfs = ProcFS::create();
  134. new_procfs->initialize();
  135. auto devptsfs = DevPtsFS::create();
  136. devptsfs->initialize();
  137. Process::initialize();
  138. Thread::initialize();
  139. Process::create_kernel_process("init_stage2", init_stage2);
  140. Process::create_kernel_process("syncd", [] {
  141. for (;;) {
  142. Syscall::sync();
  143. current->sleep(1 * TICKS_PER_SECOND);
  144. }
  145. });
  146. Process::create_kernel_process("Finalizer", [] {
  147. g_finalizer = current;
  148. current->process().set_priority(Process::LowPriority);
  149. for (;;) {
  150. Thread::finalize_dying_threads();
  151. current->block(Thread::BlockedLurking);
  152. Scheduler::yield();
  153. }
  154. });
  155. Process::create_kernel_process("NetworkTask", NetworkTask_main);
  156. Scheduler::pick_next();
  157. sti();
  158. // This now becomes the idle process :^)
  159. for (;;) {
  160. asm("hlt");
  161. }
  162. }