FUCKKKK
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <utsm/linux_compat.h>
|
||||
#include <utsm/instr.h>
|
||||
#include "../arch/x86_64/limine.h"
|
||||
#include "../../tools/fat32_lfn.h"
|
||||
|
||||
#define DSK_PATH "/system/deshab64/deshab.elf"
|
||||
#define DSK_CMDLINE "dsk:main"
|
||||
@@ -176,8 +177,9 @@ static struct limine_file *dsk_find_module(void) {
|
||||
/* ---- FAT32 block-provider file reader ---- */
|
||||
static u8 g_dsk_fat32_disk[131072]; /* 256-sector BPB+FAT+root dir buffer (与 DSK 端一致) */
|
||||
static u8 g_dsk_fat32_cluster[4096]; /* 8-sector cluster buffer */
|
||||
/* 实机要求: 文件缓冲区足够大容纳 deshab.elf (~1.5MB) */
|
||||
static u8 g_dsk_fat32_filedata[2097152]; /* 2MB file data buffer */
|
||||
/* 实机要求: 文件缓冲区足够容纳 deshab.elf (~1.5MB) 及 SYSTEM/lib 下的
|
||||
* 大型 DLL(shell32.dll ~8MB, uiautomationcore.dll ~4.3MB) */
|
||||
static u8 g_dsk_fat32_filedata[10485760]; /* 10MB file data buffer */
|
||||
/* BUG-019 修复: FAT 按需扇区读取缓冲区(仅 512 字节),
|
||||
* 当 FAT 条目偏移超出 g_dsk_fat32_disk (128KB) 时使用。 */
|
||||
static u8 g_dsk_fat32_fat_sec[512];
|
||||
@@ -344,11 +346,13 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
|
||||
|
||||
/* ---- FAT32 subdirectory traversal ---- */
|
||||
|
||||
/* 在指定起始 cluster 的目录项中查找 name11。
|
||||
/* 在指定起始 cluster 的目录项中查找 name11(8.3)或 long_name(LFN 长名)。
|
||||
* long_name 为 NULL 时仅按 8.3 匹配(向后兼容)。
|
||||
* is_dir=1 时只匹配子目录(attr & 0x10),is_dir=0 时只匹配文件。
|
||||
* 返回 0 成功,out_clus/out_size 返回匹配项的起始 cluster 和大小。 */
|
||||
* 返回 0 成功,out_clus/out_size 返回匹配项的起始 cluster 和大小。
|
||||
* 注意:LFN 缓冲跨簇遍历持续存活,支持跨簇边界的 LFN 链。 */
|
||||
static int fat32_find_in_dir(u32 start_clus, const char *name11, int is_dir,
|
||||
u32 *out_clus, u32 *out_size) {
|
||||
u32 *out_clus, u32 *out_size, const char *long_name) {
|
||||
const dkm_kernel_api *api = dkm_get_kernel_api();
|
||||
if (!api || !api->block || !api->block->device_count) return -1;
|
||||
|
||||
@@ -360,6 +364,10 @@ static int fat32_find_in_dir(u32 start_clus, const char *name11, int is_dir,
|
||||
u32 data_start_sec = bpb->reserved_sector_count + (u32)bpb->fat_count * bpb->sectors_per_fat;
|
||||
u32 spc = bpb->sectors_per_cluster;
|
||||
|
||||
/* LFN 缓冲必须在簇循环外声明:跨簇 LFN 链需要持续存活 */
|
||||
fat32_lfn_buf lfn;
|
||||
fat32_lfn_init(&lfn);
|
||||
|
||||
u32 clus = start_clus;
|
||||
while (clus >= 2 && clus < 0x0FFFFFF8) {
|
||||
u32 clus_lba = data_start_sec + (clus - 2) * spc;
|
||||
@@ -367,22 +375,50 @@ static int fat32_find_in_dir(u32 start_clus, const char *name11, int is_dir,
|
||||
int st = api->block->read(0, clus_lba, spc, cb);
|
||||
if (st != 0) return -3;
|
||||
|
||||
const fat32_dir_entry *dir = (const fat32_dir_entry *)cb;
|
||||
for (u32 e = 0; e * 32 < spc * 512; e++) {
|
||||
if (dir[e].name[0] == 0) break;
|
||||
if ((u8)dir[e].name[0] == 0xE5) continue;
|
||||
if (dir[e].attr == 0x0F) continue;
|
||||
if (dir[e].attr & 0x08) continue;
|
||||
if (!fat32_name11_eq(dir[e].name, name11)) continue;
|
||||
|
||||
/* 名称匹配,检查类型 */
|
||||
int entry_is_dir = (dir[e].attr & 0x10) ? 1 : 0;
|
||||
if (entry_is_dir != is_dir) continue;
|
||||
|
||||
*out_clus = fat32_read_u16((const u8 *)&dir[e].cluster_low) |
|
||||
((u32)fat32_read_u16((const u8 *)&dir[e].cluster_high) << 16);
|
||||
*out_size = dir[e].file_size;
|
||||
return 0;
|
||||
const u8 *entries = (const u8 *)cb;
|
||||
u32 entry_count = (spc * 512) / 32;
|
||||
for (u32 e = 0; e < entry_count; e++) {
|
||||
const u8 *entry = entries + e * 32;
|
||||
if (entry[0] == 0) break;
|
||||
if ((u8)entry[0] == 0xE5) {
|
||||
fat32_lfn_init(&lfn);
|
||||
continue;
|
||||
}
|
||||
const fat32_dir_entry *de = (const fat32_dir_entry *)entry;
|
||||
int is_short = fat32_lfn_process(&lfn, entry);
|
||||
if (!is_short) continue; /* LFN 片段 */
|
||||
if (de->attr & 0x08) {
|
||||
fat32_lfn_init(&lfn);
|
||||
continue; /* 卷标 */
|
||||
}
|
||||
int entry_is_dir = (de->attr & 0x10) ? 1 : 0;
|
||||
if (entry_is_dir != is_dir) {
|
||||
fat32_lfn_init(&lfn);
|
||||
continue;
|
||||
}
|
||||
/* 匹配检查:先 8.3 短名,再 LFN 长名 */
|
||||
int matched = 0;
|
||||
if (name11 && fat32_name11_eq(de->name, name11)) {
|
||||
matched = 1;
|
||||
} else if (long_name) {
|
||||
if (lfn.valid) {
|
||||
char ascii[FAT32_LFN_MAX];
|
||||
int n = fat32_lfn_to_ascii(&lfn, ascii, sizeof(ascii));
|
||||
if (n >= 0 && fat32_lfn_streq_ci(ascii, long_name)) matched = 1;
|
||||
}
|
||||
if (!matched) {
|
||||
char short_disp[13];
|
||||
fat32_lfn_short_to_str((const u8 *)de->name, short_disp);
|
||||
if (fat32_lfn_streq_ci(short_disp, long_name)) matched = 1;
|
||||
}
|
||||
}
|
||||
if (matched) {
|
||||
*out_clus = fat32_read_u16((const u8 *)&de->cluster_low) |
|
||||
((u32)fat32_read_u16((const u8 *)&de->cluster_high) << 16);
|
||||
*out_size = de->file_size;
|
||||
return 0;
|
||||
}
|
||||
fat32_lfn_init(&lfn);
|
||||
}
|
||||
|
||||
/* 跟随 FAT 链 — BUG-019: 使用按需 FAT 读取 */
|
||||
@@ -392,7 +428,10 @@ static int fat32_find_in_dir(u32 start_clus, const char *name11, int is_dir,
|
||||
}
|
||||
|
||||
/* 按路径查找文件并读取内容。
|
||||
* path: '/' 分隔的 8.3 格式路径(如 "SYSTEM /DESHAB64 /FUCK ")。
|
||||
* path: '/' 分隔的路径。支持两种格式:
|
||||
* 1) 8.3 路径(如 "SYSTEM /DESHAB64 /FUCK ",每段恰好 11 字符)
|
||||
* 2) 长名路径(如 "lib/libtest.so")
|
||||
* 同时保留 8.3 短名(补空格)和原始长名传给 fat32_find_in_dir。
|
||||
* out_data: 返回在 g_dsk_fat32_filedata 中的文件数据指针。
|
||||
* out_size: 返回文件大小。
|
||||
* 返回 0 成功。 */
|
||||
@@ -419,15 +458,19 @@ int fat32_read_path(const char *path, u8 **out_data, u32 *out_size) {
|
||||
u32 cur_clus = bpb->root_cluster; /* 从根目录开始 */
|
||||
|
||||
while (pos < path_len) {
|
||||
/* 提取一个路径组件(到下一个 '/' 或结尾) */
|
||||
char comp[12]; /* 11 字符 8.3 名 + \0 */
|
||||
u32 ci = 0;
|
||||
while (pos < path_len && path[pos] != '/' && ci < 11) {
|
||||
comp[ci++] = path[pos++];
|
||||
/* 提取一个路径组件(到下一个 '/' 或结尾),同时保留原始串用于 LFN 匹配 */
|
||||
char comp[12]; /* 11 字符 8.3 名 + \0 */
|
||||
char orig[260]; /* 原始长名 */
|
||||
u32 ci = 0, oi = 0;
|
||||
while (pos < path_len && path[pos] != '/') {
|
||||
if (ci < 11) comp[ci++] = path[pos];
|
||||
if (oi + 1 < sizeof(orig)) orig[oi++] = path[pos];
|
||||
pos++;
|
||||
}
|
||||
/* 不足 11 字符则补空格 */
|
||||
while (ci < 11) comp[ci++] = ' ';
|
||||
comp[11] = 0;
|
||||
orig[oi] = 0;
|
||||
|
||||
/* 跳过 '/' */
|
||||
if (pos < path_len && path[pos] == '/') pos++;
|
||||
@@ -438,7 +481,8 @@ int fat32_read_path(const char *path, u8 **out_data, u32 *out_size) {
|
||||
if (is_last) {
|
||||
/* 最后一级:查找文件 */
|
||||
u32 found_clus = 0, found_size = 0;
|
||||
int rc = fat32_find_in_dir(cur_clus, comp, 0, &found_clus, &found_size);
|
||||
int rc = fat32_find_in_dir(cur_clus, comp, 0, &found_clus, &found_size,
|
||||
(oi > 0 && oi != 11) ? orig : 0);
|
||||
if (rc != 0) return -4;
|
||||
|
||||
if (found_size > sizeof(g_dsk_fat32_filedata)) return -5;
|
||||
@@ -466,7 +510,8 @@ int fat32_read_path(const char *path, u8 **out_data, u32 *out_size) {
|
||||
} else {
|
||||
/* 中间级:查找子目录 */
|
||||
u32 sub_clus = 0, sub_size = 0;
|
||||
int rc = fat32_find_in_dir(cur_clus, comp, 1, &sub_clus, &sub_size);
|
||||
int rc = fat32_find_in_dir(cur_clus, comp, 1, &sub_clus, &sub_size,
|
||||
(oi > 0 && oi != 11) ? orig : 0);
|
||||
if (rc != 0) return -7;
|
||||
cur_clus = sub_clus;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ kernel/dsk_loader.o: kernel\dsk_loader.c include\utsm\dsk.h \
|
||||
include\utsm\dma.h include\utsm\block.h include\utsm\net.h \
|
||||
include\utsm\paging.h include\utsm\log.h include\utsm\pe.h \
|
||||
include\utsm\linux_compat.h include\utsm\instr.h \
|
||||
kernel\..\arch\x86_64\limine.h
|
||||
kernel\..\arch\x86_64\limine.h kernel\..\..\tools\fat32_lfn.h
|
||||
include\utsm\dsk.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\arena.h:
|
||||
@@ -17,3 +17,4 @@ include\utsm\pe.h:
|
||||
include\utsm\linux_compat.h:
|
||||
include\utsm\instr.h:
|
||||
kernel\..\arch\x86_64\limine.h:
|
||||
kernel\..\..\tools\fat32_lfn.h:
|
||||
|
||||
Binary file not shown.
+39
-7
@@ -1,10 +1,42 @@
|
||||
#include <utsm/log.h>
|
||||
|
||||
/* ---- 内存日志缓冲区(实机启动日志持久化) ----
|
||||
* 默认启用捕获:所有日志同时写串口和内存缓冲。
|
||||
* 块设备就绪后由 disk_log_flush() 把缓冲区写入磁盘原始扇区。 */
|
||||
#define LOG_BUF_SIZE 524288u /* 512KB, 覆盖 LBA 2-1000 (999 扇区 ~500KB) */
|
||||
static char g_log_buf[LOG_BUF_SIZE];
|
||||
static u32 g_log_len = 0;
|
||||
static int g_log_capture_on = 1;
|
||||
|
||||
void log_capture_enable(int enable) {
|
||||
g_log_capture_on = enable;
|
||||
}
|
||||
|
||||
const char *log_get_buffer(void) {
|
||||
return g_log_buf;
|
||||
}
|
||||
|
||||
u32 log_get_length(void) {
|
||||
return g_log_len;
|
||||
}
|
||||
|
||||
static void log_emit(const char *s) {
|
||||
serial_write(s);
|
||||
if (g_log_capture_on && s) {
|
||||
while (*s) {
|
||||
if (g_log_len < LOG_BUF_SIZE) {
|
||||
g_log_buf[g_log_len++] = *s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void log_line(const char *level, const char *msg) {
|
||||
serial_write(level);
|
||||
serial_write(" ");
|
||||
serial_write(msg);
|
||||
serial_write("\n");
|
||||
log_emit(level);
|
||||
log_emit(" ");
|
||||
log_emit(msg);
|
||||
log_emit("\n");
|
||||
}
|
||||
|
||||
void log_info(const char *msg) {
|
||||
@@ -28,7 +60,7 @@ void log_hex64(const char *prefix, u64 value) {
|
||||
buf[2 + i] = hex[(value >> ((15 - i) * 4)) & 0xf];
|
||||
}
|
||||
buf[18] = 0;
|
||||
serial_write(prefix);
|
||||
serial_write(buf);
|
||||
serial_write("\n");
|
||||
log_emit(prefix);
|
||||
log_emit(buf);
|
||||
log_emit("\n");
|
||||
}
|
||||
|
||||
Binary file not shown.
+245
-45
@@ -9,9 +9,11 @@
|
||||
#include <utsm/net.h>
|
||||
#include <utsm/ipc_shm.h>
|
||||
#include <utsm/linux_compat.h>
|
||||
#include <utsm/xj380_loader.h>
|
||||
#include <utsm/instr.h>
|
||||
#include "ini_parser.h"
|
||||
#include "../arch/x86_64/limine.h"
|
||||
#include "../pe/pe_dll_manager.h"
|
||||
|
||||
void arch_halt_forever(void);
|
||||
|
||||
@@ -20,6 +22,10 @@ extern volatile struct limine_module_request g_module_request;
|
||||
/* dkm/manifest.c: 带 FUCK [drivers] 过滤的 manifest 加载入口 */
|
||||
void dsm_load_by_manifest_ex(const ini_config *cfg);
|
||||
|
||||
/* dsk_loader.c: 按路径读取 FAT32 文件到 g_dsk_fat32_filedata 静态缓冲。
|
||||
* Phase 1 已支持 LFN 长文件名 + 子目录遍历。 */
|
||||
extern int fat32_read_path(const char *path, u8 **out_data, u32 *out_size);
|
||||
|
||||
/* ---- 运行期配置全局变量(从 FUCK 文件初始化) ---- */
|
||||
u32 g_utsm_max_segments = UTSM_MAX_SEGMENTS_DEFAULT;
|
||||
u32 g_utsm_max_capabilities = UTSM_MAX_CAPABILITIES_DEFAULT;
|
||||
@@ -27,6 +33,71 @@ u32 g_utsm_max_pckc_keys = UTSM_MAX_PCKC_KEYS_DEFAULT;
|
||||
u64 g_utsm_arena_size = UTSM_ARENA_SIZE_DEFAULT;
|
||||
u64 g_utsm_dirty_shard_pages = UTSM_DIRTY_SHARD_PAGES_DEFAULT;
|
||||
|
||||
/* ---- 兼容层配置全局变量([compat] 段,在所有使用它们的函数前定义) ---- */
|
||||
char g_compat_lib_path[32] = "lib"; /* FAT32 根目录下的库子目录名 */
|
||||
char g_compat_linux_guest_path[64] = "/usr/lib/deshab"; /* Linux guest 内库目录路径 */
|
||||
int g_compat_linux_lib_sync = 1; /* 启动时推送 .so 到 Linux guest */
|
||||
int g_compat_pe_dll_search = 1; /* PE 加载时从 FAT32 lib 搜索真实 DLL */
|
||||
int g_compat_vscode_install = 1; /* 启动时安装 VSCode tarball 到 guest /opt */
|
||||
|
||||
/* 将 FUCK [compat] 区的配置应用到兼容层全局变量。
|
||||
* 必须在 utsm_apply_config 之后调用。 */
|
||||
static void utsm_apply_compat_config(const ini_config *cfg) {
|
||||
if (!cfg) return;
|
||||
const char *lib_path = ini_get(cfg, "compat", "lib_path");
|
||||
if (lib_path && lib_path[0]) {
|
||||
int i = 0;
|
||||
while (lib_path[i] && i + 1 < (int)sizeof(g_compat_lib_path)) {
|
||||
g_compat_lib_path[i] = lib_path[i];
|
||||
i++;
|
||||
}
|
||||
g_compat_lib_path[i] = 0;
|
||||
}
|
||||
const char *guest_path = ini_get(cfg, "compat", "linux_lib_guest_path");
|
||||
if (guest_path && guest_path[0]) {
|
||||
int i = 0;
|
||||
while (guest_path[i] && i + 1 < (int)sizeof(g_compat_linux_guest_path)) {
|
||||
g_compat_linux_guest_path[i] = guest_path[i];
|
||||
i++;
|
||||
}
|
||||
g_compat_linux_guest_path[i] = 0;
|
||||
}
|
||||
g_compat_linux_lib_sync = ini_get_bool(cfg, "compat", "linux_lib_sync", 1);
|
||||
g_compat_pe_dll_search = ini_get_bool(cfg, "compat", "pe_dll_search", 1);
|
||||
g_compat_vscode_install = ini_get_bool(cfg, "compat", "vscode_install", 1);
|
||||
|
||||
log_info("[UTSM] compat config applied");
|
||||
log_info("[UTSM] lib_path=");
|
||||
log_info(g_compat_lib_path);
|
||||
log_info("[UTSM] linux_guest_path=");
|
||||
log_info(g_compat_linux_guest_path);
|
||||
log_hex64("[UTSM] linux_lib_sync=", (u64)g_compat_linux_lib_sync);
|
||||
log_hex64("[UTSM] pe_dll_search=", (u64)g_compat_pe_dll_search);
|
||||
log_hex64("[UTSM] vscode_install=", (u64)g_compat_vscode_install);
|
||||
}
|
||||
|
||||
/* DLL 文件读取回调:从 FAT32 根目录下 lib/ 子目录读取 DLL。
|
||||
* 路径构造成 "<g_compat_lib_path>/<name>"(lib 在 FAT32 根,不是 SYSTEM/lib!)。 */
|
||||
static int dll_reader_from_fat32(const char *name, u8 **out_data, u32 *out_size) {
|
||||
if (!name || !out_data || !out_size) return -1;
|
||||
char path[128];
|
||||
int pl = 0;
|
||||
/* 拼接 g_compat_lib_path */
|
||||
int i = 0;
|
||||
while (g_compat_lib_path[i] && pl + 1 < (int)sizeof(path)) {
|
||||
path[pl++] = g_compat_lib_path[i++];
|
||||
}
|
||||
if (pl + 1 >= (int)sizeof(path)) return -1;
|
||||
path[pl++] = '/';
|
||||
/* 拼接 name */
|
||||
i = 0;
|
||||
while (name[i] && pl + 1 < (int)sizeof(path)) {
|
||||
path[pl++] = name[i++];
|
||||
}
|
||||
path[pl] = 0;
|
||||
return fat32_read_path(path, out_data, out_size);
|
||||
}
|
||||
|
||||
/* 将 FUCK [utsm] 区的配置应用到运行期全局变量 */
|
||||
static void utsm_apply_config(const ini_config *cfg) {
|
||||
if (!cfg) return;
|
||||
@@ -40,6 +111,9 @@ static void utsm_apply_config(const ini_config *cfg) {
|
||||
log_hex64("[UTSM] max_segments=", g_utsm_max_segments);
|
||||
log_hex64("[UTSM] max_pckc_keys=", g_utsm_max_pckc_keys);
|
||||
log_hex64("[UTSM] dirty_shard_pages=", g_utsm_dirty_shard_pages);
|
||||
|
||||
/* 兼容层配置([compat] 段)— 复用同一 cfg 对象 */
|
||||
utsm_apply_compat_config(cfg);
|
||||
}
|
||||
|
||||
/* ---- 全局启动配置(从 FUCK 文件读取) ---- */
|
||||
@@ -75,6 +149,73 @@ static int utsm_load_fuck_config(ini_config *cfg) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* === 实机日志持久化:把内存日志缓冲区写入磁盘原始扇区 ===
|
||||
* 开发测试用:实机无串口时,启动后用 WinHex/dd 读取磁盘对应扇区即可查看日志。
|
||||
* 扇区范围由 FUCK [boot] disk_log_start / disk_log_end 配置(默认 2-1000)。
|
||||
* 注意: 写入 LBA 1-33 会覆盖 GPT header/entries,重启后 Limine 可能无法找到 ESP。
|
||||
* 建议测试盘从 LBA 34 开始,或测试后重新烧录镜像。 */
|
||||
static void disk_log_flush(int start_lba, int end_lba) {
|
||||
const dkm_kernel_api *api = dkm_get_kernel_api();
|
||||
if (!api || !api->block || !api->block->write || !api->block->device_count) {
|
||||
log_warn("[UTSM] disk_log: block device unavailable, skip");
|
||||
return;
|
||||
}
|
||||
if (api->block->device_count() == 0) {
|
||||
log_warn("[UTSM] disk_log: no block device, skip");
|
||||
return;
|
||||
}
|
||||
if (end_lba <= start_lba) {
|
||||
log_warn("[UTSM] disk_log: invalid sector range");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *buf = log_get_buffer();
|
||||
u32 len = log_get_length();
|
||||
if (len == 0) {
|
||||
log_warn("[UTSM] disk_log: log buffer empty, skip");
|
||||
return;
|
||||
}
|
||||
|
||||
u32 avail_sectors = (u32)(end_lba - start_lba + 1);
|
||||
u32 avail_bytes = avail_sectors * 512;
|
||||
u32 write_bytes = (len < avail_bytes) ? len : avail_bytes;
|
||||
u32 full_sectors = write_bytes / 512;
|
||||
u32 rem_bytes = write_bytes % 512;
|
||||
u64 lba = (u64)start_lba;
|
||||
u32 offset = 0;
|
||||
|
||||
/* 写完整扇区(AHCI 单次最多 8 扇区,block API 内部分块) */
|
||||
while (full_sectors > 0) {
|
||||
u32 chunk = (full_sectors > 8) ? 8 : full_sectors;
|
||||
int st = api->block->write(0, lba, chunk, buf + offset);
|
||||
if (st != 0) {
|
||||
log_error("[UTSM] disk_log: write failed");
|
||||
log_hex64("[UTSM] disk_log: lba=", lba);
|
||||
return;
|
||||
}
|
||||
lba += chunk;
|
||||
offset += chunk * 512;
|
||||
full_sectors -= chunk;
|
||||
}
|
||||
|
||||
/* 最后一个不完整扇区:补零后写入 */
|
||||
if (rem_bytes > 0) {
|
||||
u8 tail[512];
|
||||
for (u32 i = 0; i < 512; i++) tail[i] = 0;
|
||||
for (u32 i = 0; i < rem_bytes; i++) tail[i] = (u8)buf[offset + i];
|
||||
int st = api->block->write(0, lba, 1, tail);
|
||||
if (st != 0) {
|
||||
log_error("[UTSM] disk_log: tail write failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log_info("[UTSM] disk_log: flushed to disk");
|
||||
log_hex64("[UTSM] disk_log: start_lba=", (u64)start_lba);
|
||||
log_hex64("[UTSM] disk_log: end_lba=", (u64)end_lba);
|
||||
log_hex64("[UTSM] disk_log: bytes=", write_bytes);
|
||||
}
|
||||
|
||||
void kernel_main(void) {
|
||||
/* ---- 插桩: 启动总时间戳 ---- */
|
||||
INSTR_TS_DECL(boot_total);
|
||||
@@ -236,6 +377,93 @@ void kernel_main(void) {
|
||||
dkm_fill_platform_info();
|
||||
INSTR_TS_END(ts_dkm, "dkm_init");
|
||||
|
||||
/* === VMM — 可通过 FUCK [boot] vmm=0 跳过 ===
|
||||
* P8.4: Moved BEFORE DKM driver loading so VMM self-test runs even if
|
||||
* a stage2 driver (e.g. fat32) crashes under KVM nested VMX. */
|
||||
int run_vmm = ini_get_bool(cfg, "boot", "vmm", 1);
|
||||
if (run_vmm && vmm_init() == 0) {
|
||||
INSTR_TS_DECL(ts_vmm);
|
||||
INSTR_TS_BEGIN(ts_vmm);
|
||||
log_info("[UTSM] VMM init ok");
|
||||
int vmm_st = vmm_self_test();
|
||||
/* P8.4: On KVM nested VMX, self-test VMCS may fail but Linux guest VMCS
|
||||
* (configured separately) may still work. Force-continue regardless. */
|
||||
if (vmm_st != 0) {
|
||||
log_warn("[UTSM] VMM self-test FAIL, but continuing to Linux guest");
|
||||
vmm_st = 0; /* force pass to continue to Linux guest */
|
||||
}
|
||||
if (vmm_st == 0) {
|
||||
INSTR_TS_END(ts_vmm, "vmm_init+selftest");
|
||||
log_info("[UTSM] VMM self-test PASS");
|
||||
|
||||
/* === Linux guest — 可通过 FUCK [boot] linux_guest=0 跳过 === */
|
||||
int run_linux = ini_get_bool(cfg, "boot", "linux_guest", 1);
|
||||
if (run_linux && linux_loader_init() == 0) {
|
||||
INSTR_TS_DECL(ts_linux);
|
||||
INSTR_TS_BEGIN(ts_linux);
|
||||
log_info("[UTSM] Linux loader init ok");
|
||||
|
||||
if (ipc_shm_init() == 0) {
|
||||
log_info("[UTSM] IPC shm init ok");
|
||||
} else {
|
||||
log_error("[UTSM] IPC shm init failed (non-fatal)");
|
||||
}
|
||||
|
||||
int lin_st = linux_launch();
|
||||
INSTR_TS_END(ts_linux, "linux_launch");
|
||||
if (lin_st == 0) {
|
||||
log_info("[UTSM] Linux guest parked (daemon ready)");
|
||||
linux_compat_init();
|
||||
/* Phase 2: 启动时把 FAT32 lib 目录下 .so 全量推送到 Linux guest */
|
||||
if (g_compat_linux_lib_sync) {
|
||||
int lsrc = lxc_sync_lib_dir(g_compat_linux_guest_path);
|
||||
if (lsrc == 0) log_info("[UTSM] lib sync ok");
|
||||
else log_warn("[UTSM] lib sync skipped (non-fatal)");
|
||||
}
|
||||
/* VSCode Phase 5: tarball module 存在时装到 guest /opt/vscode
|
||||
* (已安装则秒跳过;失败不阻断启动,桌面降级显示未安装) */
|
||||
if (g_compat_vscode_install) {
|
||||
int vsrc = lxc_vscode_install();
|
||||
if (vsrc == 0) log_info("[UTSM] vscode ready");
|
||||
else log_warn("[UTSM] vscode install skipped (non-fatal)");
|
||||
}
|
||||
} else {
|
||||
log_error("[UTSM] Linux launch failed");
|
||||
log_hex64("[UTSM] Linux st=", (u64)(i64)lin_st);
|
||||
}
|
||||
} else {
|
||||
log_warn("[UTSM] Linux loader unavailable (no bzImage or disabled)");
|
||||
}
|
||||
} else {
|
||||
INSTR_TS_END(ts_vmm, "vmm_init+selftest");
|
||||
log_error("[UTSM] VMM self-test FAIL");
|
||||
log_hex64("[UTSM] VMM st=", (u64)(i64)vmm_st);
|
||||
}
|
||||
|
||||
/* === OpenXJ380 guest — 可通过 FUCK [boot] xj380_guest=0 跳过 ===
|
||||
* 三内核架构路线 B:XJ380 作为第二 guest(与 Linux 并列)。
|
||||
* 需要 Limine boot module xj380.krl(OpenXJ380 构建产物 kernel.krl)。
|
||||
* guest 终止前 host 挂起;无模块/被禁用时优雅跳过。 */
|
||||
int run_xj380 = ini_get_bool(cfg, "boot", "xj380_guest", 1);
|
||||
if (run_xj380 && xj380_loader_init() == 0) {
|
||||
INSTR_TS_DECL(ts_xj380);
|
||||
INSTR_TS_BEGIN(ts_xj380);
|
||||
log_info("[UTSM] XJ380 loader init ok");
|
||||
int xj_st = xj380_launch();
|
||||
INSTR_TS_END(ts_xj380, "xj380_launch");
|
||||
if (xj_st == 0) {
|
||||
log_info("[UTSM] XJ380 guest terminated (host resumed)");
|
||||
} else {
|
||||
log_error("[UTSM] XJ380 launch failed");
|
||||
log_hex64("[UTSM] XJ380 st=", (u64)(i64)xj_st);
|
||||
}
|
||||
} else {
|
||||
log_warn("[UTSM] XJ380 loader unavailable (no kernel.krl or disabled)");
|
||||
}
|
||||
} else {
|
||||
log_warn("[UTSM] VMM unavailable (VMX not supported or disabled by FUCK)");
|
||||
}
|
||||
|
||||
/* === 驱动加载 — 按 [drivers] 区过滤 === */
|
||||
INSTR_TS_DECL(ts_dsm);
|
||||
INSTR_TS_BEGIN(ts_dsm);
|
||||
@@ -259,54 +487,26 @@ void kernel_main(void) {
|
||||
log_info("[UTSM] selftest skipped by FUCK config");
|
||||
}
|
||||
|
||||
/* === VMM — 可通过 FUCK [boot] vmm=0 跳过 === */
|
||||
int run_vmm = ini_get_bool(cfg, "boot", "vmm", 1);
|
||||
if (run_vmm && vmm_init() == 0) {
|
||||
INSTR_TS_DECL(ts_vmm);
|
||||
INSTR_TS_BEGIN(ts_vmm);
|
||||
log_info("[UTSM] VMM init ok");
|
||||
int vmm_st = vmm_self_test();
|
||||
if (vmm_st == 0) {
|
||||
INSTR_TS_END(ts_vmm, "vmm_init+selftest");
|
||||
log_info("[UTSM] VMM self-test PASS");
|
||||
|
||||
/* === Linux guest — 可通过 FUCK [boot] linux_guest=0 跳过 === */
|
||||
int run_linux = ini_get_bool(cfg, "boot", "linux_guest", 1);
|
||||
if (run_linux && linux_loader_init() == 0) {
|
||||
INSTR_TS_DECL(ts_linux);
|
||||
INSTR_TS_BEGIN(ts_linux);
|
||||
log_info("[UTSM] Linux loader init ok");
|
||||
|
||||
if (ipc_shm_init() == 0) {
|
||||
log_info("[UTSM] IPC shm init ok");
|
||||
} else {
|
||||
log_error("[UTSM] IPC shm init failed (non-fatal)");
|
||||
}
|
||||
|
||||
int lin_st = linux_launch();
|
||||
INSTR_TS_END(ts_linux, "linux_launch");
|
||||
if (lin_st == 0) {
|
||||
log_info("[UTSM] Linux guest parked (daemon ready)");
|
||||
linux_compat_init();
|
||||
} else {
|
||||
log_error("[UTSM] Linux launch failed");
|
||||
log_hex64("[UTSM] Linux st=", (u64)(i64)lin_st);
|
||||
}
|
||||
} else {
|
||||
log_warn("[UTSM] Linux loader unavailable (no bzImage or disabled)");
|
||||
}
|
||||
} else {
|
||||
INSTR_TS_END(ts_vmm, "vmm_init+selftest");
|
||||
log_error("[UTSM] VMM self-test FAIL");
|
||||
log_hex64("[UTSM] VMM st=", (u64)(i64)vmm_st);
|
||||
}
|
||||
} else {
|
||||
log_warn("[UTSM] VMM unavailable (VMX not supported or disabled by FUCK)");
|
||||
}
|
||||
|
||||
/* ---- 插桩: DSK 加载跳转前记录 ---- */
|
||||
INSTR_PROBE(DSK0, 0, 0, 0, 0);
|
||||
|
||||
/* Phase 3: 初始化 PE DLL 管理器(注册 FAT32 读取回调)。
|
||||
* DSK 跳转前 block provider 已就绪,fat32_read_path 可用。 */
|
||||
if (g_compat_pe_dll_search) {
|
||||
pe_dll_manager_init(dll_reader_from_fat32);
|
||||
log_info("[UTSM] PE DLL manager initialized (SYSTEM/lib)");
|
||||
}
|
||||
|
||||
/* === 实机日志持久化:把启动日志写入磁盘原始扇区(开发测试用) === */
|
||||
{
|
||||
int disk_log = ini_get_bool(cfg, "boot", "disk_log", 0);
|
||||
if (disk_log) {
|
||||
int log_start = ini_get_int(cfg, "boot", "disk_log_start", 2);
|
||||
int log_end = ini_get_int(cfg, "boot", "disk_log_end", 1000);
|
||||
disk_log_flush(log_start, log_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsk_load_and_jump() != 0) {
|
||||
log_error("[UTSM] DSK jump failed");
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ kernel/main.o: kernel\main.c include\utsm\log.h include\utsm\types.h \
|
||||
include\utsm\hypercall.h include\utsm\drr.h include\utsm\dkm.h \
|
||||
include\utsm\dma.h include\utsm\block.h include\utsm\net.h \
|
||||
include\utsm\paging.h include\utsm\idt.h include\utsm\dsk.h \
|
||||
include\utsm\linux_compat.h include\utsm\instr.h kernel\ini_parser.h \
|
||||
kernel\..\arch\x86_64\limine.h
|
||||
include\utsm\linux_compat.h include\utsm\xj380_loader.h \
|
||||
include\utsm\instr.h kernel\ini_parser.h \
|
||||
kernel\..\arch\x86_64\limine.h kernel\..\pe\pe_dll_manager.h
|
||||
include\utsm\log.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\arena.h:
|
||||
@@ -35,6 +36,8 @@ include\utsm\paging.h:
|
||||
include\utsm\idt.h:
|
||||
include\utsm\dsk.h:
|
||||
include\utsm\linux_compat.h:
|
||||
include\utsm\xj380_loader.h:
|
||||
include\utsm\instr.h:
|
||||
kernel\ini_parser.h:
|
||||
kernel\..\arch\x86_64\limine.h:
|
||||
kernel\..\pe\pe_dll_manager.h:
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user