init.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright (c) 2021, Nico Weber <thakis@chromium.org>
  3. * Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
  4. * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
  5. * Copyright (c) 2022, the SerenityOS developers.
  6. * Copyright (c) 2022, Filiph Sandström <filiph.sandstrom@filfatstudios.com>
  7. *
  8. * SPDX-License-Identifier: BSD-2-Clause
  9. */
  10. #include <AK/Format.h>
  11. #include <AK/Types.h>
  12. #include <Kernel/Arch/InterruptManagement.h>
  13. #include <Kernel/Arch/Interrupts.h>
  14. #include <Kernel/Arch/Processor.h>
  15. #include <Kernel/Arch/aarch64/ASM_wrapper.h>
  16. #include <Kernel/Arch/aarch64/BootPPMParser.h>
  17. #include <Kernel/Arch/aarch64/CPU.h>
  18. #include <Kernel/Arch/aarch64/RPi/Framebuffer.h>
  19. #include <Kernel/Arch/aarch64/RPi/Mailbox.h>
  20. #include <Kernel/Arch/aarch64/RPi/UART.h>
  21. #include <Kernel/Arch/aarch64/Registers.h>
  22. #include <Kernel/Arch/aarch64/TrapFrame.h>
  23. #include <Kernel/CommandLine.h>
  24. #include <Kernel/Devices/DeviceManagement.h>
  25. #include <Kernel/FileSystem/VirtualFileSystem.h>
  26. #include <Kernel/Graphics/Console/BootFramebufferConsole.h>
  27. #include <Kernel/KSyms.h>
  28. #include <Kernel/Memory/MemoryManager.h>
  29. #include <Kernel/Panic.h>
  30. #include <Kernel/Scheduler.h>
  31. #include <Kernel/Storage/StorageManagement.h>
  32. #include <Kernel/TTY/VirtualConsole.h>
  33. typedef void (*ctor_func_t)();
  34. extern ctor_func_t start_heap_ctors[];
  35. extern ctor_func_t end_heap_ctors[];
  36. extern ctor_func_t start_ctors[];
  37. extern ctor_func_t end_ctors[];
  38. // FIXME: Share this with the Intel Prekernel.
  39. extern uintptr_t __stack_chk_guard;
  40. uintptr_t __stack_chk_guard;
  41. READONLY_AFTER_INIT bool g_in_early_boot;
  42. namespace Kernel {
  43. static void draw_logo(u8* framebuffer_data);
  44. static u32 query_firmware_version();
  45. extern "C" [[noreturn]] void halt();
  46. extern "C" [[noreturn]] void init();
  47. ALWAYS_INLINE static Processor& bootstrap_processor()
  48. {
  49. alignas(Processor) static u8 bootstrap_processor_storage[sizeof(Processor)];
  50. return (Processor&)bootstrap_processor_storage;
  51. }
  52. Atomic<Graphics::Console*> g_boot_console;
  53. VirtualConsole* tty0;
  54. ProcessID g_init_pid { 0 };
  55. static void init_stage2(void*);
  56. void init_stage2(void*)
  57. {
  58. Process::register_new(Process::current());
  59. auto firmware_version = query_firmware_version();
  60. dmesgln("Firmware version: {}", firmware_version);
  61. VirtualFileSystem::initialize();
  62. StorageManagement::the().initialize(kernel_command_line().root_device(), kernel_command_line().is_force_pio(), kernel_command_line().is_nvme_polling_enabled());
  63. if (VirtualFileSystem::the().mount_root(StorageManagement::the().root_filesystem()).is_error()) {
  64. PANIC("VirtualFileSystem::mount_root failed");
  65. }
  66. // Switch out of early boot mode.
  67. g_in_early_boot = false;
  68. LockRefPtr<Thread> thread;
  69. auto userspace_init = kernel_command_line().userspace_init();
  70. auto init_args = kernel_command_line().userspace_init_args();
  71. auto init_or_error = Process::try_create_user_process(thread, userspace_init, UserID(0), GroupID(0), move(init_args), {}, tty0);
  72. if (init_or_error.is_error())
  73. PANIC("init_stage2: Error spawning init process: {}", init_or_error.error());
  74. g_init_pid = init_or_error.value()->pid();
  75. thread->set_priority(THREAD_PRIORITY_HIGH);
  76. Process::current().sys$exit(0);
  77. VERIFY_NOT_REACHED();
  78. }
  79. extern "C" [[noreturn]] void init()
  80. {
  81. g_in_early_boot = true;
  82. // FIXME: Don't hardcode this
  83. multiboot_memory_map_t mmap[] = {
  84. { sizeof(struct multiboot_mmap_entry) - sizeof(u32),
  85. (u64)0x0,
  86. (u64)0x3F000000,
  87. MULTIBOOT_MEMORY_AVAILABLE }
  88. };
  89. multiboot_memory_map = mmap;
  90. multiboot_memory_map_count = 1;
  91. dbgln("Welcome to Serenity OS!");
  92. dbgln("Imagine this being your ideal operating system.");
  93. dbgln("Observed deviations from that ideal are shortcomings of your imagination.");
  94. dbgln();
  95. CommandLine::early_initialize("");
  96. new (&bootstrap_processor()) Processor();
  97. bootstrap_processor().early_initialize(0);
  98. // We call the constructors of kmalloc.cpp separately, because other constructors in the Kernel
  99. // might rely on being able to call new/kmalloc in the constructor. We do have to run the
  100. // kmalloc constructors, because kmalloc_init relies on that.
  101. for (ctor_func_t* ctor = start_heap_ctors; ctor < end_heap_ctors; ctor++)
  102. (*ctor)();
  103. kmalloc_init();
  104. bootstrap_processor().initialize(0);
  105. load_kernel_symbol_table();
  106. CommandLine::initialize();
  107. dmesgln("Starting SerenityOS...");
  108. Memory::MemoryManager::initialize(0);
  109. DeviceManagement::initialize();
  110. SysFSComponentRegistry::initialize();
  111. DeviceManagement::the().attach_null_device(*NullDevice::must_initialize());
  112. // Invoke all static global constructors in the kernel.
  113. // Note that we want to do this as early as possible.
  114. for (ctor_func_t* ctor = start_ctors; ctor < end_ctors; ctor++)
  115. (*ctor)();
  116. auto& framebuffer = RPi::Framebuffer::the();
  117. if (framebuffer.initialized()) {
  118. g_boot_console = &try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(PhysicalAddress((PhysicalPtr)framebuffer.gpu_buffer()), framebuffer.width(), framebuffer.height(), framebuffer.pitch()).value().leak_ref();
  119. draw_logo(static_cast<Graphics::BootFramebufferConsole*>(g_boot_console.load())->unsafe_framebuffer_data());
  120. }
  121. initialize_interrupts();
  122. InterruptManagement::initialize();
  123. Processor::enable_interrupts();
  124. // Note: We have to disable interrupts otherwise Scheduler::timer_tick might be called before the scheduler is started.
  125. Processor::disable_interrupts();
  126. TimeManagement::initialize(0);
  127. Process::initialize();
  128. Scheduler::initialize();
  129. {
  130. LockRefPtr<Thread> init_stage2_thread;
  131. (void)Process::create_kernel_process(init_stage2_thread, KString::must_create("init_stage2"sv), init_stage2, nullptr, THREAD_AFFINITY_DEFAULT, Process::RegisterProcess::No);
  132. // We need to make sure we drop the reference for init_stage2_thread
  133. // before calling into Scheduler::start, otherwise we will have a
  134. // dangling Thread that never gets cleaned up
  135. }
  136. Scheduler::start();
  137. VERIFY_NOT_REACHED();
  138. }
  139. class QueryFirmwareVersionMboxMessage : RPi::Mailbox::Message {
  140. public:
  141. u32 version;
  142. QueryFirmwareVersionMboxMessage()
  143. : RPi::Mailbox::Message(0x0000'0001, 4)
  144. {
  145. version = 0;
  146. }
  147. };
  148. static u32 query_firmware_version()
  149. {
  150. struct __attribute__((aligned(16))) {
  151. RPi::Mailbox::MessageHeader header;
  152. QueryFirmwareVersionMboxMessage query_firmware_version;
  153. RPi::Mailbox::MessageTail tail;
  154. } message_queue;
  155. if (!RPi::Mailbox::the().send_queue(&message_queue, sizeof(message_queue))) {
  156. return 0xffff'ffff;
  157. }
  158. return message_queue.query_firmware_version.version;
  159. }
  160. extern "C" const u32 serenity_boot_logo_start;
  161. extern "C" const u32 serenity_boot_logo_size;
  162. static void draw_logo(u8* framebuffer_data)
  163. {
  164. BootPPMParser logo_parser(reinterpret_cast<u8 const*>(&serenity_boot_logo_start), serenity_boot_logo_size);
  165. if (!logo_parser.parse()) {
  166. dbgln("Failed to parse boot logo.");
  167. return;
  168. }
  169. dbgln("Boot logo size: {} ({} x {})", serenity_boot_logo_size, logo_parser.image.width, logo_parser.image.height);
  170. auto& framebuffer = RPi::Framebuffer::the();
  171. auto fb_ptr = framebuffer_data;
  172. auto image_left = (framebuffer.width() - logo_parser.image.width) / 2;
  173. auto image_right = image_left + logo_parser.image.width;
  174. auto image_top = (framebuffer.height() - logo_parser.image.height) / 2;
  175. auto image_bottom = image_top + logo_parser.image.height;
  176. auto logo_pixels = logo_parser.image.pixel_data;
  177. for (u32 y = 0; y < framebuffer.height(); y++) {
  178. for (u32 x = 0; x < framebuffer.width(); x++) {
  179. if (x >= image_left && x < image_right && y >= image_top && y < image_bottom) {
  180. switch (framebuffer.pixel_order()) {
  181. case RPi::Framebuffer::PixelOrder::RGB:
  182. fb_ptr[0] = logo_pixels[0];
  183. fb_ptr[1] = logo_pixels[1];
  184. fb_ptr[2] = logo_pixels[2];
  185. break;
  186. case RPi::Framebuffer::PixelOrder::BGR:
  187. fb_ptr[0] = logo_pixels[2];
  188. fb_ptr[1] = logo_pixels[1];
  189. fb_ptr[2] = logo_pixels[0];
  190. break;
  191. default:
  192. dbgln("Unsupported pixel format");
  193. VERIFY_NOT_REACHED();
  194. }
  195. logo_pixels += 3;
  196. } else {
  197. fb_ptr[0] = 0xBD;
  198. fb_ptr[1] = 0xBD;
  199. fb_ptr[2] = 0xBD;
  200. }
  201. fb_ptr[3] = 0xFF;
  202. fb_ptr += 4;
  203. }
  204. fb_ptr += framebuffer.pitch() - framebuffer.width() * 4;
  205. }
  206. }
  207. }