main.swift 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //
  2. // Copyright 2026 Aarav Ravindra Kharade
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. // -
  17. // ArkOS Runtime Daemon (arkrt)
  18. // -
  19. import CSystem
  20. @_silgen_name("ark_wayland_server_init")
  21. func ark_wayland_server_init()
  22. @_silgen_name("ark_wayland_server_run")
  23. func ark_wayland_server_run()
  24. // The primary system daemon, running as PID 1.
  25. // Responsible for:
  26. //
  27. // 1. Mounting system and vendor partitions
  28. // 2. Configuring network interfaces
  29. // 3. Starting the IPC server for inter-process communication
  30. // 4. Discovering and starting system services (display, UI, etc.)
  31. // 5. Launching the boot splash animation
  32. // 6. Monitoring all child processes and respawning on crash
  33. //
  34. // Boot Sequence:
  35. // - arkrt (PID 1)
  36. // - IPC Server (thread)
  37. // - NetworkService (thread)
  38. // - display service (child process)
  39. // - swift_splash (child process — temporary)
  40. // - ui_test (child process — launched by ServiceManager)
  41. //
  42. // -
  43. // - Phase 1: System Initialization (PID 1) -
  44. // Redirect stdout/stderr to serial console for QEMU log capture
  45. let serialFd = ark_open2("/dev/ttyS0", O_RDWR)
  46. if serialFd >= 0 {
  47. dup2(serialFd, 1) // stdout → serial
  48. dup2(serialFd, 2) // stderr → serial
  49. if serialFd > 2 { close(serialFd) }
  50. }
  51. // Mount core kernel filesystems required by Swift and system APIs
  52. LogManager.log("ArkOS Runtime Daemon starting as PID 1...", component: "ark.log")
  53. LogManager.log("PID=\(getpid()), UID=\(getuid())", component: "ark.log")
  54. // Report system resources
  55. let cpuCores = ResourceController.getCPUCoreCount()
  56. let totalRAM = ResourceController.getTotalMemory() / 1024 / 1024
  57. let initialRSS = ResourceController.checkMemoryUsage() / 1024
  58. LogManager.log("System: \(cpuCores) CPU cores, \(totalRAM) MB RAM, RSS=\(initialRSS) KB", component: "ark.log")
  59. // - Phase 2: Mount System Partitions -
  60. LogManager.log("Mounting system partitions...", component: "ark.log")
  61. if true {
  62. let items = ["dev_node"]
  63. LogManager.log("arkrt: /dev contents: \(items.joined(separator: ", "))")
  64. }
  65. func mountPartition(devices: [String], mountPoint: String, fsType: String) {
  66. mkdir(mountPoint, 0o755)
  67. if fsType == "tmpfs" {
  68. let result = mount("tmpfs", mountPoint, fsType, 0, nil)
  69. if result == 0 {
  70. LogManager.log("Mounted tmpfs → \(mountPoint) (\(fsType))", component: "ark.log")
  71. } else {
  72. LogManager.log("Failed to mount tmpfs to \(mountPoint)", level: .warn, component: "ark.log")
  73. }
  74. return
  75. }
  76. // Wait up to 3 seconds total for ANY of the devices to appear
  77. var waited = 0
  78. while waited < 30 {
  79. for device in devices {
  80. if access(device, F_OK) == 0 {
  81. let result = mount(device, mountPoint, fsType, 0, nil)
  82. if result == 0 {
  83. LogManager.log("Mounted \(device) → \(mountPoint) (\(fsType))", component: "ark.log")
  84. return
  85. }
  86. }
  87. }
  88. usleep(100_000) // 100ms
  89. waited += 1
  90. }
  91. LogManager.log("Failed to mount any device to \(mountPoint)", level: .warn, component: "ark.log")
  92. }
  93. // Mount tmpfs for runtime state
  94. mountPartition(devices: ["tmpfs"], mountPoint: "/run", fsType: "tmpfs")
  95. mountPartition(devices: ["tmpfs"], mountPoint: "/tmp", fsType: "tmpfs")
  96. // Create essential runtime directories
  97. mkdir("/run", 0o755)
  98. mkdir("/var/log", 0o755)
  99. mkdir("/etc", 0o755)
  100. mkdir("/system", 0o755)
  101. mkdir("/vendor", 0o755)
  102. // Attempt to mount system and vendor from disk images (block devices)
  103. let systemDevices = ["/dev/vdb", "/dev/sdb", "/dev/hdb", "/dev/sda2"]
  104. let vendorDevices = ["/dev/vdc", "/dev/sdc", "/dev/hdc", "/dev/sda3"]
  105. mountPartition(devices: systemDevices, mountPoint: "/system", fsType: "ext4")
  106. mountPartition(devices: vendorDevices, mountPoint: "/vendor", fsType: "ext4")
  107. // - Phase 3: Network Configuration -
  108. LogManager.log("Configuring network interfaces...", component: "ark.log")
  109. NetworkService.shared.configureInterfaces()
  110. NetworkService.shared.startMonitoring()
  111. // - Phase 4: IPC Server -
  112. LogManager.log("Starting IPC server...", component: "ark.log")
  113. var server = IPCServer()
  114. server.start()
  115. // - Phase 5: Display Initialization -
  116. setenv("XDG_RUNTIME_DIR", "/run", 1)
  117. setenv("WAYLAND_DEBUG", "1", 1)
  118. LogManager.log("Initializing monolithic display daemon...", component: "ark.log")
  119. ArkCompositor.shared.start()
  120. renderBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: scrW * scrH * bpp)
  121. LogManager.log("Starting display event loop...", component: "ark.log")
  122. // The wayland thread is now started internally inside ArkCompositor.shared.start()
  123. LogManager.log("Rendering boot splash...", component: "ark.log")
  124. drawSwiftSplash()
  125. LogManager.log("Starting system services...", component: "ark.log")
  126. ServiceManager.shared.startAllServices()
  127. var lastResolution: String = ""
  128. ResourceController.executeOnCorePool {
  129. while true {
  130. // Monitor all managed services for crashes
  131. ServiceManager.shared.monitorServices()
  132. // Periodic resource health check
  133. let ram = ResourceController.checkMemoryUsage()
  134. if ram > 1_500_000_000 { // 1.5 GB
  135. LogManager.log("HIGH MEMORY WARNING: \(ram / 1024 / 1024) MB RSS", level: .warn, component: "ark.log")
  136. }
  137. // Check for resolution changes
  138. if let fp = fopen("/sys/class/graphics/fb0/virtual_size", "r") {
  139. var buf = [CChar](repeating: 0, count: 64)
  140. if fgets(&buf, Int32(buf.count), fp) != nil {
  141. let currentRes = String(cString: buf)
  142. if lastResolution != "" && currentRes != lastResolution {
  143. LogManager.log("Resolution changed from \(lastResolution) to \(currentRes).", component: "ark.log")
  144. // Handle dynamic resolution changes here if needed
  145. }
  146. lastResolution = currentRes
  147. }
  148. fclose(fp)
  149. }
  150. // Log heartbeat every ~60 iterations (2 min)
  151. sleep(2)
  152. }
  153. }
  154. // - Phase 8: Main App -
  155. // The main thread runs the UI setup app natively.
  156. // Background queues (IPC, network monitor, display daemon, and service manager)
  157. // continue running in the CorePool.
  158. // LogManager.log("Starting SetupApp on main thread...", component: "ark.log")
  159. // SetupApp.main()
  160. // Keep PID 1 alive
  161. while true {
  162. sleep(60)
  163. }