2026-02-08 00:13:16 +08:00
|
|
|
|
using CMLeonOS.Logger;
|
|
|
|
|
|
using CMLeonOS.Settings;
|
2026-02-02 18:08:24 +08:00
|
|
|
|
using Cosmos.HAL;
|
2026-02-08 00:13:16 +08:00
|
|
|
|
using Cosmos.HAL.BlockDevice;
|
|
|
|
|
|
using Cosmos.HAL.Drivers.Video;
|
2026-02-02 22:32:02 +08:00
|
|
|
|
using Cosmos.System.FileSystem;
|
|
|
|
|
|
using Cosmos.System.FileSystem.FAT;
|
|
|
|
|
|
using Cosmos.System.FileSystem.VFS;
|
2026-02-08 00:13:16 +08:00
|
|
|
|
using Cosmos.System.Graphics;
|
|
|
|
|
|
using Cosmos.System.Graphics.Fonts;
|
2026-02-02 18:08:24 +08:00
|
|
|
|
using Cosmos.System.Network.Config;
|
2026-02-02 19:38:56 +08:00
|
|
|
|
using Cosmos.System.Network.IPv4;
|
2026-02-08 00:13:16 +08:00
|
|
|
|
using Cosmos.System.Network.IPv4.UDP.DHCP;
|
2026-01-31 19:14:13 +08:00
|
|
|
|
using System;
|
2026-01-30 21:55:35 +08:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
2026-02-02 18:08:24 +08:00
|
|
|
|
using System.Reflection.Metadata.Ecma335;
|
2026-02-08 18:13:51 +08:00
|
|
|
|
using System.Runtime.CompilerServices;
|
2026-02-08 00:13:16 +08:00
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
2026-02-02 18:08:24 +08:00
|
|
|
|
using System.Text;
|
2026-01-30 21:55:35 +08:00
|
|
|
|
using Sys = Cosmos.System;
|
|
|
|
|
|
|
|
|
|
|
|
namespace CMLeonOS
|
|
|
|
|
|
{
|
|
|
|
|
|
public class Kernel : Sys.Kernel
|
|
|
|
|
|
{
|
2026-02-04 23:49:08 +08:00
|
|
|
|
private static CMLeonOS.Logger.Logger _logger = CMLeonOS.Logger.Logger.Instance;
|
|
|
|
|
|
|
2026-01-30 21:55:35 +08:00
|
|
|
|
// 创建全局CosmosVFS实例
|
2026-02-02 19:38:56 +08:00
|
|
|
|
public static Sys.FileSystem.CosmosVFS fs = new Sys.FileSystem.CosmosVFS();
|
2026-02-03 23:41:11 +08:00
|
|
|
|
public static Shell shell;
|
|
|
|
|
|
public static UserSystem userSystem;
|
2026-01-30 23:36:08 +08:00
|
|
|
|
|
|
|
|
|
|
public static bool FixMode = false;
|
2026-02-02 05:22:25 +08:00
|
|
|
|
public static DateTime SystemStartTime;
|
|
|
|
|
|
|
2026-02-02 19:38:56 +08:00
|
|
|
|
public static Cosmos.HAL.NetworkDevice NetworkDevice = null;
|
|
|
|
|
|
public static string IPAddress = "Unknown";
|
2026-02-08 00:13:16 +08:00
|
|
|
|
|
|
|
|
|
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.font.psf")]
|
|
|
|
|
|
public static readonly byte[] file;
|
2026-02-09 02:04:58 +08:00
|
|
|
|
|
|
|
|
|
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.GitCommit.txt")]
|
|
|
|
|
|
public static readonly byte[] gitCommitFile;
|
|
|
|
|
|
|
2026-02-12 00:53:29 +08:00
|
|
|
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.BuildTime.txt")]
|
|
|
|
|
|
public static readonly byte[] buildTimeFile;
|
|
|
|
|
|
|
2026-02-08 18:56:32 +08:00
|
|
|
|
public static void ShowError(string message)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.ForegroundColor = ConsoleColor.Red;
|
|
|
|
|
|
Console.WriteLine($"{message}");
|
|
|
|
|
|
Console.ResetColor();
|
|
|
|
|
|
}
|
2026-02-02 19:38:56 +08:00
|
|
|
|
|
2026-01-30 21:55:35 +08:00
|
|
|
|
protected override void BeforeRun()
|
|
|
|
|
|
{
|
2026-02-16 21:02:04 +08:00
|
|
|
|
BootMenuAction bootAction = BootMenu.Show();
|
2026-02-08 00:13:16 +08:00
|
|
|
|
|
2026-02-16 21:02:04 +08:00
|
|
|
|
switch (bootAction)
|
|
|
|
|
|
{
|
|
|
|
|
|
case BootMenuAction.Reboot:
|
|
|
|
|
|
Sys.Power.Reboot();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BootMenuAction.Shutdown:
|
|
|
|
|
|
Sys.Power.Shutdown();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BootMenuAction.NormalBoot:
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Console.Clear();
|
2026-02-25 16:51:27 +08:00
|
|
|
|
// Console.WriteLine("Kernel load done!");
|
|
|
|
|
|
// Console.WriteLine(@"----------------------------------------------------------");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
Console.WriteLine(@" ____ __ __ _ ___ ____ ");
|
|
|
|
|
|
Console.WriteLine(@" / ___| \/ | | ___ ___ _ __ / _ \/ ___| ");
|
|
|
|
|
|
Console.WriteLine(@" | | | |\/| | | / _ \/ _ \| '_ \| | | \___ \ ");
|
|
|
|
|
|
Console.WriteLine(@" | |___| | | | |__| __/ (_) | | | | |_| |___) |");
|
2026-01-30 23:36:08 +08:00
|
|
|
|
Console.WriteLine(@" \____|_| |_|_____\___|\___/|_| |_|____/|____/ ");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
Console.WriteLine();
|
2026-02-05 01:43:30 +08:00
|
|
|
|
Console.WriteLine("The CMLeonOS Project");
|
2026-02-19 17:37:42 +08:00
|
|
|
|
Console.WriteLine("(C) LeonOS 2 Developer Team 2025-2026. All rights reserved.");
|
|
|
|
|
|
Console.WriteLine(@"----------------------------------------------------------");
|
2026-02-05 01:43:30 +08:00
|
|
|
|
|
2026-01-30 21:55:35 +08:00
|
|
|
|
// 注册VFS
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Starting VFS initialization");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Sys.FileSystem.VFS.VFSManager.RegisterVFS(fs);
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Success("Kernel", "VFS initialized successfully");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
2026-02-06 16:15:24 +08:00
|
|
|
|
Settings.SettingsManager.LoadSettings();
|
|
|
|
|
|
_logger.Info("Kernel", "Settings loaded successfully");
|
|
|
|
|
|
|
2026-01-31 14:01:50 +08:00
|
|
|
|
// 显示可用空间(动态单位)
|
2026-01-30 21:55:35 +08:00
|
|
|
|
var available_space = fs.GetAvailableFreeSpace(@"0:\");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
string spaceWithUnit = FormatBytes(available_space);
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", $"Available Free Space: {spaceWithUnit}");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
|
|
|
|
|
// 显示文件系统类型
|
|
|
|
|
|
var fs_type = fs.GetFileSystemType(@"0:\");
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", $"File System Type: {fs_type}");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
// 检查并创建system文件夹
|
|
|
|
|
|
string systemFolderPath = @"0:\system";
|
|
|
|
|
|
if (!System.IO.Directory.Exists(systemFolderPath))
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
System.IO.Directory.CreateDirectory(systemFolderPath);
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Created system folder at 0:\\system");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-08 01:53:59 +08:00
|
|
|
|
// 检查并创建apps文件夹
|
|
|
|
|
|
string appsFolderPath = @"0:\apps";
|
|
|
|
|
|
if (!System.IO.Directory.Exists(appsFolderPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
System.IO.Directory.CreateDirectory(appsFolderPath);
|
|
|
|
|
|
_logger.Info("Kernel", "Created apps folder at 0:\\apps");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-30 21:55:35 +08:00
|
|
|
|
// 初始化用户系统
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Initializing user system");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
userSystem = new UserSystem();
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Success("Kernel", "User system initialized");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
2026-02-09 02:04:58 +08:00
|
|
|
|
// 读取 Git Commit hash
|
|
|
|
|
|
if (gitCommitFile != null && gitCommitFile.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Version.GitCommit = System.Text.Encoding.UTF8.GetString(gitCommitFile);
|
|
|
|
|
|
_logger.Info("Kernel", $"Git Commit: {Version.GitCommit}");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
Version.GitCommit = "unknown";
|
|
|
|
|
|
_logger.Warning("Kernel", "Failed to read Git Commit, using 'unknown'");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Version.GitCommit = "unknown";
|
|
|
|
|
|
_logger.Warning("Kernel", "Git Commit file not found, using 'unknown'");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 00:53:29 +08:00
|
|
|
|
// 读取 Build Time
|
|
|
|
|
|
if (buildTimeFile != null && buildTimeFile.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
string buildTime = System.Text.Encoding.UTF8.GetString(buildTimeFile);
|
|
|
|
|
|
_logger.Info("Kernel", $"Build Time: {buildTime}");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.Warning("Kernel", "Failed to read Build Time");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.Warning("Kernel", "Build Time file not found");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-01 18:05:54 +08:00
|
|
|
|
// 检查env.dat文件是否存在,如果不存在则创建并设置Test环境变量
|
|
|
|
|
|
string envFilePath = @"0:\system\env.dat";
|
|
|
|
|
|
if (!System.IO.File.Exists(envFilePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
System.IO.File.WriteAllText(envFilePath, "Test=123");
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Created env.dat with Test=123");
|
2026-02-01 18:05:54 +08:00
|
|
|
|
}
|
2026-02-02 18:08:24 +08:00
|
|
|
|
|
2026-02-06 16:15:24 +08:00
|
|
|
|
// 记录系统启动时间(用于uptime命令)
|
|
|
|
|
|
SystemStartTime = DateTime.Now;
|
|
|
|
|
|
_logger.Info("Kernel", $"System started at: {SystemStartTime.ToString("yyyy-MM-dd HH:mm:ss")}");
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化网络
|
|
|
|
|
|
_logger.Info("Kernel", "Starting network initialization");
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Cosmos.HAL.NetworkDevice.Devices.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("No network devices are available.");
|
|
|
|
|
|
}
|
|
|
|
|
|
NetworkDevice = NetworkDevice.Devices[0];
|
|
|
|
|
|
_logger.Info("Kernel", $"Network device found: {NetworkDevice.Name}");
|
|
|
|
|
|
|
|
|
|
|
|
using var dhcp = new DHCPClient();
|
|
|
|
|
|
if (NetworkDevice.Ready == true) {
|
|
|
|
|
|
_logger.Success("Kernel", "Network device ready.");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.Error("Kernel", "Network device is not ready");
|
|
|
|
|
|
}
|
|
|
|
|
|
dhcp.SendDiscoverPacket();
|
|
|
|
|
|
|
|
|
|
|
|
IPAddress = NetworkConfiguration.CurrentAddress.ToString();
|
|
|
|
|
|
_logger.Info("Kernel", $"Local IP: {IPAddress}");
|
|
|
|
|
|
|
|
|
|
|
|
string gateway = NetworkConfigManager.Instance.GetGateway();
|
|
|
|
|
|
_logger.Info("Kernel", $"Gateway: {gateway}");
|
|
|
|
|
|
|
|
|
|
|
|
string dns = NetworkConfigManager.Instance.GetDNS();
|
|
|
|
|
|
_logger.Info("Kernel", $"DNS Server: {dns}");
|
|
|
|
|
|
|
|
|
|
|
|
_logger.Success("Kernel", "Network started successfully");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.Error("Kernel", $"Network initialization failed: {ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-02 18:08:24 +08:00
|
|
|
|
// 输出系统启动-初始化完成后的时间
|
|
|
|
|
|
TimeSpan uptime = DateTime.Now - Kernel.SystemStartTime;
|
|
|
|
|
|
|
|
|
|
|
|
// Console.WriteLine("System started: " + Kernel.SystemStartTime.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
|
// Console.WriteLine("Current time: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
|
// Console.WriteLine();
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化运行时间
|
|
|
|
|
|
int days = uptime.Days;
|
|
|
|
|
|
int hours = uptime.Hours;
|
|
|
|
|
|
int minutes = uptime.Minutes;
|
|
|
|
|
|
int seconds = uptime.Seconds;
|
|
|
|
|
|
|
2026-02-04 23:49:08 +08:00
|
|
|
|
// Console.WriteLine($"System uptime: {days} days, {hours} hours, {minutes} minutes, {seconds} seconds");
|
|
|
|
|
|
_logger.Info("Kernel", $"System initialization completed in {days} days, {hours} hours, {minutes} minutes, {seconds} seconds");
|
2026-02-02 19:38:56 +08:00
|
|
|
|
// Console.WriteLine($"Total uptime: {uptime.TotalHours:F2} hours");
|
2026-02-01 18:05:54 +08:00
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
// 循环直到登录成功或退出
|
|
|
|
|
|
while (true)
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
// 第一次启动,设置管理员账户
|
|
|
|
|
|
if (!userSystem.HasUsers)
|
|
|
|
|
|
{
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "First time setup - creating admin account");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
userSystem.FirstTimeSetup();
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Success("Kernel", "Admin account created successfully");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
// 后续启动,需要登录
|
|
|
|
|
|
else
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
// 循环直到登录成功
|
|
|
|
|
|
while (!userSystem.Login())
|
|
|
|
|
|
{
|
|
|
|
|
|
// 登录失败,继续尝试
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", $"User '{userSystem.CurrentUsername}' logged in successfully");
|
|
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
// 登录成功后,初始化Shell
|
2026-02-01 15:21:17 +08:00
|
|
|
|
shell = new Shell(userSystem);
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
|
|
|
|
|
// 检查并执行启动脚本
|
|
|
|
|
|
ExecuteStartupScript();
|
2026-02-05 23:57:21 +08:00
|
|
|
|
|
2026-02-24 21:48:08 +08:00
|
|
|
|
ExecuteStartupTest();
|
|
|
|
|
|
|
2026-02-05 23:57:21 +08:00
|
|
|
|
if (System.IO.File.Exists("0:\\system\\zen"))
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("=====================================");
|
|
|
|
|
|
Console.WriteLine(" The Zen of CMLeonOS ");
|
|
|
|
|
|
Console.WriteLine("(For the dreamer at 0x100000)");
|
|
|
|
|
|
Console.WriteLine("=====================================");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("Memory has bounds, but thought breaks all frame,");
|
|
|
|
|
|
Console.WriteLine("Bare metal no layers, code bears its name.");
|
|
|
|
|
|
Console.WriteLine("A boot's brief spark, all systems ignite,");
|
|
|
|
|
|
Console.WriteLine("Errors in registers, roots in code's flight.");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("Simplicity beats the redundant's vain race,");
|
|
|
|
|
|
Console.WriteLine("Stability outshines the radical's chase.");
|
|
|
|
|
|
Console.WriteLine("Hardware ne'er lies, code holds the wise key,");
|
|
|
|
|
|
Console.WriteLine("Interrupts not chaos, scheduling sets free.");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("Binary's cold shell, no breath, no soul,");
|
|
|
|
|
|
Console.WriteLine("Kernel's warm core, makes the machine whole.");
|
|
|
|
|
|
Console.WriteLine("From zero to one, the boot path we tread,");
|
|
|
|
|
|
Console.WriteLine("From one to forever, guard every thread.");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("Build the kernel in zen, step by step, line by line,");
|
|
|
|
|
|
Console.WriteLine("A bug brings new wake, a line brings new shine.");
|
|
|
|
|
|
}
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
|
|
|
|
|
// 运行Shell(用户可以输入exit退出)
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Starting Shell");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
shell.Run();
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Shell exited");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果用户输入了exit,Shell.Run()会返回,继续循环
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2026-02-08 18:56:32 +08:00
|
|
|
|
if (ex.Message.Contains("Read only"))
|
|
|
|
|
|
{
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
var formatWindow = new CMLeonOS.UI.Window(
|
|
|
|
|
|
new CMLeonOS.UI.Rect(10, 5, 60, 12),
|
|
|
|
|
|
"Format Disk",
|
|
|
|
|
|
() => { },
|
|
|
|
|
|
true
|
|
|
|
|
|
);
|
|
|
|
|
|
formatWindow.Render();
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 8);
|
|
|
|
|
|
global::System.Console.Write("Disk not formatted");
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Yellow, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 9);
|
|
|
|
|
|
global::System.Console.Write("Warning: This will erase all data!");
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 11);
|
|
|
|
|
|
global::System.Console.Write("Press any key to format...");
|
|
|
|
|
|
|
|
|
|
|
|
global::System.Console.ReadKey();
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
Disk targetDisk = fs.Disks[0];
|
|
|
|
|
|
CreateMBRandPartitionTable(targetDisk);
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.Clear();
|
|
|
|
|
|
formatWindow.Render();
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 8);
|
|
|
|
|
|
global::System.Console.Write("Disk formatted successfully!");
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 9);
|
|
|
|
|
|
global::System.Console.Write("Restarting in 3 seconds...");
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Thread.Sleep(3000);
|
|
|
|
|
|
Sys.Power.Reboot();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception exe)
|
|
|
|
|
|
{
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.Clear();
|
|
|
|
|
|
formatWindow.Render();
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 8);
|
|
|
|
|
|
global::System.Console.Write("Format failed!");
|
|
|
|
|
|
|
|
|
|
|
|
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
|
|
|
|
|
|
global::System.Console.SetCursorPosition(12, 9);
|
|
|
|
|
|
global::System.Console.Write($"Error: {exe.Message}");
|
|
|
|
|
|
|
|
|
|
|
|
global::System.Console.ReadKey();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
Console.Clear();
|
|
|
|
|
|
Console.BackgroundColor = ConsoleColor.Red;
|
|
|
|
|
|
Console.ForegroundColor = ConsoleColor.White;
|
|
|
|
|
|
Console.Clear();
|
2026-02-08 23:51:15 +08:00
|
|
|
|
Console.Beep();
|
2026-02-08 18:56:32 +08:00
|
|
|
|
Console.WriteLine(":(");
|
2026-02-08 23:51:15 +08:00
|
|
|
|
Console.WriteLine("A problem has been detected and CMLeonOS has been shut down to prevent damage to your computer.");
|
2026-02-09 02:04:58 +08:00
|
|
|
|
|
|
|
|
|
|
string gitCommit = "unknown";
|
|
|
|
|
|
if (gitCommitFile != null && gitCommitFile.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
gitCommit = System.Text.Encoding.UTF8.GetString(gitCommitFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-08 18:56:32 +08:00
|
|
|
|
Console.WriteLine($"Error information: {ex.Message}");
|
2026-02-09 02:04:58 +08:00
|
|
|
|
Console.WriteLine($"Build version: {gitCommit}");
|
2026-02-08 23:51:15 +08:00
|
|
|
|
Console.WriteLine("The operating system cannot recover from this exception and has halted immediately.");
|
|
|
|
|
|
Console.WriteLine("If this is the first time you've seen this stop error screen, restart your computer.");
|
|
|
|
|
|
Console.WriteLine("If this screen appears again, follow these steps:");
|
|
|
|
|
|
Console.WriteLine("1. Check the system logs to ensure all kernel modules are loaded correctly.");
|
|
|
|
|
|
Console.WriteLine("2. Record the system version and steps to reproduce the error.");
|
2026-02-09 21:33:21 +08:00
|
|
|
|
Console.WriteLine("3. Send an post to the CMLeonOS official forum.");
|
|
|
|
|
|
Console.WriteLine("Contact us via https://lbbs.ecuil.com/#/thread/category/10, including the error information for support.");
|
2026-02-11 02:09:32 +08:00
|
|
|
|
Console.WriteLine("Please include the error information, system build version, runtime environment, and operation steps before the crash.");
|
2026-02-08 23:51:15 +08:00
|
|
|
|
Console.WriteLine("Warning: Unsaved data in memory will be lost due to the emergency system shutdown.");
|
|
|
|
|
|
Console.WriteLine("Press any key to restart.");
|
2026-02-08 18:56:32 +08:00
|
|
|
|
Console.ReadKey();
|
|
|
|
|
|
Sys.Power.Reboot();
|
|
|
|
|
|
}
|
2026-02-08 18:13:51 +08:00
|
|
|
|
// try {
|
|
|
|
|
|
// Disk targetDisk = fs.Disks[0];
|
|
|
|
|
|
// CreateMBRandPartitionTable(targetDisk);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// catch (Exception exe)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// Console.WriteLine($"Error creating MBR and partition table: {exe.Message}");
|
|
|
|
|
|
// }
|
|
|
|
|
|
// Console.WriteLine("Done.");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-08 18:13:51 +08:00
|
|
|
|
// 我他妈居然成功了,我在没有任何文档的情况下研究出来了
|
2026-02-08 18:56:32 +08:00
|
|
|
|
private void CreateMBRandPartitionTable(Disk disk)
|
|
|
|
|
|
{
|
|
|
|
|
|
disk.Clear();
|
|
|
|
|
|
ulong diskSize = (ulong)(disk.Size / 1024 / 1024);
|
|
|
|
|
|
uint partSize = (uint)(diskSize - 2);
|
2026-02-08 18:13:51 +08:00
|
|
|
|
|
2026-02-08 18:56:32 +08:00
|
|
|
|
disk.CreatePartition((int)partSize);
|
2026-02-08 18:13:51 +08:00
|
|
|
|
|
2026-02-08 18:56:32 +08:00
|
|
|
|
var part = disk.Partitions[disk.Partitions.Count - 1];
|
|
|
|
|
|
disk.FormatPartition(0, "FAT32", true);
|
|
|
|
|
|
// Console.WriteLine($"Partition type: {part.GetType()}");
|
|
|
|
|
|
}
|
2026-02-08 18:13:51 +08:00
|
|
|
|
|
2026-01-31 14:01:50 +08:00
|
|
|
|
private void ExecuteStartupScript()
|
|
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
string startupFilePath = @"0:\system\startup.cm";
|
2026-01-31 14:01:50 +08:00
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 检查启动脚本文件是否存在
|
|
|
|
|
|
if (System.IO.File.Exists(startupFilePath))
|
|
|
|
|
|
{
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Startup script found, executing...");
|
|
|
|
|
|
|
2026-01-31 14:01:50 +08:00
|
|
|
|
// 读取启动脚本内容
|
|
|
|
|
|
string[] lines = System.IO.File.ReadAllLines(startupFilePath);
|
|
|
|
|
|
|
|
|
|
|
|
// 检查文件是否为空
|
|
|
|
|
|
if (lines.Length == 0 || (lines.Length == 1 && string.IsNullOrWhiteSpace(lines[0])))
|
|
|
|
|
|
{
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Warning("Kernel", "Startup script is empty, skipping");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Executing startup script...");
|
2026-02-26 13:33:53 +08:00
|
|
|
|
// Console.WriteLine("--------------------------------");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
|
|
|
|
|
|
// 逐行执行命令
|
|
|
|
|
|
foreach (string line in lines)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 跳过空行和注释行
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(line) || line.Trim().StartsWith("#"))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 执行命令
|
2026-01-31 20:50:07 +08:00
|
|
|
|
// Console.WriteLine($"Executing: {line}");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
shell.ExecuteCommand(line);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-26 13:33:53 +08:00
|
|
|
|
// Console.WriteLine("--------------------------------");
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Success("Kernel", "Startup script execution completed");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 启动脚本不存在,创建空文件
|
2026-02-05 11:20:09 +08:00
|
|
|
|
_logger.Info("Kernel", "Startup script not found, creating empty file...");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
System.IO.File.WriteAllText(startupFilePath, "");
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Info("Kernel", "Created empty startup script at 0:\\system\\startup.cm");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2026-02-04 23:49:08 +08:00
|
|
|
|
_logger.Error("Kernel", $"Error executing startup script: {ex.Message}");
|
2026-01-31 14:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-24 21:48:08 +08:00
|
|
|
|
private void ExecuteStartupTest()
|
|
|
|
|
|
{
|
2026-02-26 13:33:53 +08:00
|
|
|
|
Console.WriteLine("------------------------------------------------------");
|
|
|
|
|
|
Console.WriteLine($"Welcome to {Version.DisplayVersion}");
|
|
|
|
|
|
Console.WriteLine("* Documentation: https://cmleonos.jjmm.ink/");
|
2026-02-26 13:47:47 +08:00
|
|
|
|
Console.WriteLine("* Forum: https://lbbs.ecuil.com/#/category/10");
|
|
|
|
|
|
// Console.WriteLine("");
|
2026-02-26 13:33:53 +08:00
|
|
|
|
|
2026-02-26 13:47:47 +08:00
|
|
|
|
// 感觉排版有点割裂,先注释掉
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Red;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Yellow;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Green;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Cyan;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Blue;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Magenta;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.White;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkBlue;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkCyan;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkGreen;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkYellow;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkRed;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Gray;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkGray;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.DarkMagenta;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.BackgroundColor = ConsoleColor.Black;
|
|
|
|
|
|
// Console.Write(" ");
|
|
|
|
|
|
// Console.WriteLine("");
|
|
|
|
|
|
// Console.ResetColor();
|
2026-02-26 13:33:53 +08:00
|
|
|
|
Console.WriteLine("------------------------------------------------------");
|
2026-02-24 21:48:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-31 14:01:50 +08:00
|
|
|
|
private string FormatBytes(long bytes)
|
|
|
|
|
|
{
|
|
|
|
|
|
string[] units = { "B", "KB", "MB", "GB", "TB" };
|
|
|
|
|
|
int unitIndex = 0;
|
|
|
|
|
|
double size = bytes;
|
|
|
|
|
|
|
|
|
|
|
|
while (size >= 1024 && unitIndex < units.Length - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
size /= 1024;
|
|
|
|
|
|
unitIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $"{size:F2} {units[unitIndex]}";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-30 21:55:35 +08:00
|
|
|
|
protected override void Run()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (shell != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
shell.Run();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|