Files
CMLeonOS/Kernel.cs

363 lines
16 KiB
C#
Raw Normal View History

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-02 19:38:56 +08:00
2026-01-30 21:55:35 +08:00
protected override void BeforeRun()
{
2026-02-08 00:13:16 +08:00
// 我认了,我用默认字体
// try
// {
// PCScreenFont screenFont = PCScreenFont.LoadFont(file);
// VGAScreen.SetFont(screenFont.CreateVGAFont(), screenFont.Height);
// VGAScreen.SetGraphicsMode(VGADriver.ScreenSize.Size720x480, ColorDepth.ColorDepth32);
// }
// catch (Exception ex)
// {
// 我不认我试着转换成Base64
// 我认了
PCScreenFont defaultFont = PCScreenFont.Default;
VGAScreen.SetFont(defaultFont.CreateVGAFont(), defaultFont.Height);
// Console.WriteLine($"{defaultFont.Height}");
// Console.WriteLine($"{defaultFont.Width}");
// VGAScreen.SetGraphicsMode(VGADriver.ScreenSize.Size720x480, ColorDepth.ColorDepth32);
// Console.WriteLine($"Error loading font: {ex.Message}");
// }
2026-02-02 02:01:52 +08:00
Console.WriteLine("Kernel load done!");
2026-01-31 19:14:13 +08:00
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-01-30 21:55:35 +08:00
Console.WriteLine("By LeonOS 2 Developement Team");
2026-02-05 01:43:30 +08:00
Console.WriteLine(@"-------------------------------------------------");
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-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
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
// 如果用户输入了exitShell.Run()会返回,继续循环
2026-01-30 21:55:35 +08:00
}
}
}
catch (Exception ex)
{
2026-02-06 16:15:24 +08:00
Console.Clear();
Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
Console.Clear();
Console.WriteLine(":(");
Console.WriteLine("A problem has been detected and CMLeonOS has been shutdown to prevent damage to your computer.");
Console.WriteLine($"Error information: {ex.Message}");
Console.WriteLine("If this is the first time you've seen this stop error screen, restart your computer and email to leonmmcoset@outlook.com WITH THE ERROR INFORMATION for technical support.");
Console.WriteLine("Press any keys to restart.");
2026-02-02 22:32:02 +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
// 我他妈居然成功了,我在没有任何文档的情况下研究出来了
// private void CreateMBRandPartitionTable(Disk disk)
// {
// disk.Clear();
// ulong diskSize = (ulong)(disk.Size / 1024 / 1024);
// uint partSize = (uint)(diskSize - 2);
// disk.CreatePartition((int)partSize);
// var part = disk.Partitions[disk.Partitions.Count - 1];
// disk.FormatPartition(0, "FAT32", true);
// Console.WriteLine($"Partition type: {part.GetType()}");
// }
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...");
Console.WriteLine("--------------------------------");
// 逐行执行命令
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);
}
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
}
}
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();
}
}
}
}