ohhhhhhhhhhh (exclude linux-extra-rootfs.img build artifact)

This commit is contained in:
Linehu
2026-10-01 23:13:42 +08:00
parent 737a2cb0db
commit 1074962546
533 changed files with 133239 additions and 5460 deletions
+67 -21
View File
@@ -22,6 +22,7 @@
#define DESHAB_FAT32_IO_H
#include "fat32_lfn.h"
#include "fat32_part.h"
/* ---- block 设备函数类型(与 shell/DSK 一致:index 参数固定 0) ---- */
typedef int (*f32_block_read_fn)(u32 index, u64 lba, u32 count, void *buf);
@@ -60,27 +61,39 @@ static inline int f32_neq11(const char *a, const char *b) {
#define F32_DATA_BYTES 262144
#endif
static u8 f32_disk[131072]; /* 256 扇区 BPB+FAT+根目录缓存 */
static u8 f32_cluster[4096]; /* 单簇缓冲 */
static u8 f32_cluster[FAT32_MAX_CLUSTER_BYTES]; /* 单簇缓冲:ESP>=4GiB 时为 32KiB */
static u8 f32_data[F32_DATA_BYTES]; /* 文件数据缓冲 */
static int f32_disk_loaded = 0; /* f32_disk 是否已加载 BPB+FAT */
static u32 f32_lba_base = 0; /* GPT ESP start (0 for superfloppy / SATA) */
/* 初始化:注入 block_read/block_write 函数指针 */
static inline void f32_init(f32_block_read_fn rd, f32_block_write_fn wr) {
f32_blk_read = rd;
f32_blk_write = wr;
f32_disk_loaded = 0;
f32_lba_base = 0;
}
static inline int f32_read_sectors(u32 lba, u32 count, u8 *out) {
return f32_blk_read ? f32_blk_read(0, lba, count, out) : -1;
return f32_blk_read ? f32_blk_read(0, (u64)lba + f32_lba_base, count, out) : -1;
}
static inline int f32_write_sectors(u32 lba, u32 count, const u8 *buf) {
return f32_blk_write ? f32_blk_write(0, lba, count, buf) : -1;
return f32_blk_write ? f32_blk_write(0, (u64)lba + f32_lba_base, count, buf) : -1;
}
static inline int f32_bpb_ok_at(u32 abs_lba) {
u8 sec[512];
const f32_bpb *bpb;
if (!f32_blk_read || f32_blk_read(0, abs_lba, 1, sec) != 0) return 0;
bpb = (const f32_bpb *)sec;
return (bpb->boot_sig == 0xAA55 && bpb->bps == 512 && bpb->spf != 0 && bpb->root_clus >= 2);
}
/* 确保 f32_disk 已加载 BPB+FAT+根目录(256 扇区) */
static inline int f32_disk_load(void) {
if (f32_disk_loaded) return 0;
f32_lba_base = (u32)fat32_part_probe(f32_blk_read, 0);
if (!f32_bpb_ok_at(f32_lba_base)) return -2;
if (f32_read_sectors(0, 256, f32_disk) != 0) return -1;
const f32_bpb *bpb = (const f32_bpb *)f32_disk;
if (bpb->boot_sig != 0xAA55 || bpb->bps != 512) return -2;
@@ -177,7 +190,7 @@ static inline int f32_read_root_file(const char *name11, u8 **out_data, u32 *out
if ((u64)lba * 512 + (u64)spc * 512 <= 256ULL * 512)
cb = f32_disk + (u64)lba * 512;
else {
if (f32_read_sectors(lba, 8, f32_cluster) != 0) return -4;
if (f32_read_sectors(lba, spc, f32_cluster) != 0) return -4;
cb = f32_cluster;
}
if (f32_find_in_root(cb, spc, name11, &found_clus, &found_size, 0) == 0) { found = 1; break; }
@@ -197,7 +210,7 @@ static inline int f32_read_root_file(const char *name11, u8 **out_data, u32 *out
if ((u64)fc_lba * 512 + (u64)spc * 512 <= 256ULL * 512)
fb = f32_disk + (u64)fc_lba * 512;
else {
if (f32_read_sectors(fc_lba, 8, f32_cluster) != 0) return -7;
if (f32_read_sectors(fc_lba, spc, f32_cluster) != 0) return -7;
fb = f32_cluster;
}
for (u32 b = 0; b < fc_bytes; b++) dst[b] = fb[b];
@@ -662,7 +675,7 @@ static inline int f32_list_root(f32_list_cb emit, void *user_data) {
if ((u64)lba * 512 + (u64)spc * 512 <= 256ULL * 512)
cb = f32_disk + (u64)lba * 512;
else {
if (f32_read_sectors(lba, 8, f32_cluster) != 0) return -4;
if (f32_read_sectors(lba, spc, f32_cluster) != 0) return -4;
cb = f32_cluster;
}
const f32_dirent *dir = (const f32_dirent *)cb;
@@ -685,18 +698,7 @@ done:
/* ---- 子目录遍历支持(Phase 2.2 fileman 扩展) ---- */
/* 目录条目(供 fileman 等工具使用) */
typedef struct {
char name[13]; /* 8.3 显示名 */
u32 clus; /* 首簇号 */
u32 size; /* 文件大小(目录为 0) */
u8 attr;
u8 is_dir;
u8 has_lfn; /* 1=long_name 字段有效 */
char long_name[260]; /* LFN 长文件名(ASCII) */
} f32_entry;
typedef int (*f32_list_entry_cb)(const f32_entry *e, void *user_data);
/* f32_entry / f32_list_entry_cb 定义已移至 fat32_lfn.h(本头包含之)。 */
/* 列举指定目录簇的内容(含 LFN 长文件名)。
* dir_clus = 0 表示根目录(自动从 BPB 取 root_clus)。
@@ -717,7 +719,7 @@ static inline int f32_list_dir(u32 dir_clus, f32_list_entry_cb emit, void *user_
if ((u64)lba * 512 + (u64)spc * 512 <= 256ULL * 512)
cb = f32_disk + (u64)lba * 512;
else {
if (f32_read_sectors(lba, 8, f32_cluster) != 0) return -4;
if (f32_read_sectors(lba, spc, f32_cluster) != 0) return -4;
cb = f32_cluster;
}
const u8 *entries = (const u8 *)cb;
@@ -781,7 +783,7 @@ static inline int f32_read_file_by_clus(u32 clus, u32 size, u8 *out_buf, u32 buf
if ((u64)fc_lba * 512 + (u64)spc * 512 <= 256ULL * 512)
fb = f32_disk + (u64)fc_lba * 512;
else {
if (f32_read_sectors(fc_lba, 8, f32_cluster) != 0) return -7;
if (f32_read_sectors(fc_lba, spc, f32_cluster) != 0) return -7;
fb = f32_cluster;
}
for (u32 b = 0; b < fc_bytes; b++) dst[b] = fb[b];
@@ -822,7 +824,7 @@ static inline int f32_find_in_dir_lfn(u32 dir_clus, const char *long_name,
if ((u64)lba * 512 + (u64)spc * 512 <= 256ULL * 512)
cb = f32_disk + (u64)lba * 512;
else {
if (f32_read_sectors(lba, 8, f32_cluster) != 0) return -4;
if (f32_read_sectors(lba, spc, f32_cluster) != 0) return -4;
cb = f32_cluster;
}
const u8 *entries = (const u8 *)cb;
@@ -961,6 +963,50 @@ static inline int f32_read_path_lfn(const char *path, u8 **out_data, u32 *out_si
return 0;
}
/* 按长路径读取文件到调用者指定缓冲(流式直读,绕过 f32_data 尺寸上限)。
* path : '/' 分隔的长文件名路径(如 "system/font/simhei_16.dbf")
* dst : 目标缓冲(如固定地址字库区)
* cap : 缓冲容量(字节)
* out_size : 返回文件大小(可为 0)
* 返回 0 成功,负值失败(-4 = 文件超过 cap)。 */
static inline int f32_read_path_lfn_to(const char *path, u8 *dst, u32 cap, u32 *out_size) {
if (!path || !dst) return -1;
if (f32_disk_load() != 0) return -1;
/* 分离目录部分与文件名 */
u32 path_len = 0;
while (path[path_len]) path_len++;
u32 last_slash = 0xFFFFFFFFu;
for (u32 i = 0; i < path_len; i++) {
if (path[i] == '/') last_slash = i;
}
const char *fname = (last_slash == 0xFFFFFFFFu) ? path : path + last_slash + 1;
/* 定位父目录簇 */
u32 dir_clus = 0;
if (last_slash == 0xFFFFFFFFu) {
const f32_bpb *bpb = (const f32_bpb *)f32_disk;
dir_clus = bpb->root_clus;
} else {
char dirpath[260];
u32 dn = last_slash;
if (dn >= sizeof(dirpath)) dn = sizeof(dirpath) - 1;
for (u32 i = 0; i < dn; i++) dirpath[i] = path[i];
dirpath[dn] = 0;
if (f32_find_path_dir_lfn(dirpath, &dir_clus) != 0) return -2;
}
/* 在父目录中查找文件 */
u32 file_clus = 0, file_size = 0;
if (f32_find_in_dir_lfn(dir_clus, fname, 0, &file_clus, &file_size) != 0) return -3;
if (file_size > cap) return -4;
/* 读取文件数据到目标缓冲 */
if (f32_read_file_by_clus(file_clus, file_size, dst, cap) != 0) return -5;
if (out_size) *out_size = file_size;
return 0;
}
/* 按长路径写入文件(存在则替换,不存在则在父目录中新建 8.3 项)。
* path : '/' 分隔路径(如 "system/deshab64/FUCK"),文件名段必须可转 8.3
* 返回 0 成功,负值失败(-6 = 文件名不是合法 8.3)。 */
+13
View File
@@ -42,6 +42,19 @@ typedef struct {
int valid; /* 1=LFN 链完整且 checksum 与短名项匹配 */
} fat32_lfn_buf;
/* 目录条目(供 fileman / linux_compat 列举使用)。 */
typedef struct {
char name[13];
u32 clus;
u32 size;
u8 attr;
u8 is_dir;
u8 has_lfn;
char long_name[260];
} f32_entry;
typedef int (*f32_list_entry_cb)(const f32_entry *e, void *user_data);
/* 初始化/清空 LFN 缓冲 */
static inline void fat32_lfn_init(fat32_lfn_buf *buf) {
buf->count = 0;
+69
View File
@@ -0,0 +1,69 @@
/* fat32_part.h — locate a FAT32 volume on a superfloppy or GPT ESP.
*
* Callers already define u8/u16/u32/u64. The read callback matches
* dkm_block_api.read: (index, lba, count, buf).
*/
#ifndef DESHAB_FAT32_PART_H
#define DESHAB_FAT32_PART_H
/* pack_system_image.sh uses 64 sectors/cluster (32KiB) when the ESP is >= 4GiB.
* Every FAT32 cluster buffer in DSK/UTSM/userland must cover that size. */
#ifndef FAT32_MAX_CLUSTER_BYTES
#define FAT32_MAX_CLUSTER_BYTES 32768u
#endif
typedef int (*fat32_part_read_fn)(u32 index, u64 lba, u32 count, void *buf);
static inline int fat32_part_bpb_ok(const u8 *sec) {
u32 spf;
if (!sec) return 0;
if (sec[510] != 0x55 || sec[511] != 0xAA) return 0;
if (sec[11] != 0x00 || sec[12] != 0x02) return 0; /* 512-byte sectors */
spf = (u32)sec[36] | ((u32)sec[37] << 8) | ((u32)sec[38] << 16) | ((u32)sec[39] << 24);
if (spf == 0) return 0;
if (sec[13] == 0) return 0; /* sectors per cluster */
return 1;
}
static inline u64 fat32_part_r64(const u8 *p) {
return (u64)p[0] | ((u64)p[1] << 8) | ((u64)p[2] << 16) | ((u64)p[3] << 24)
| ((u64)p[4] << 32) | ((u64)p[5] << 40) | ((u64)p[6] << 48) | ((u64)p[7] << 56);
}
/* EFI System Partition type GUID c12a7328-f81f-11d2-ba4b-00a0c93ec93b */
static const u8 fat32_part_esp_guid[16] = {
0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
};
/* Return the LBA of the FAT32 BPB relative to the whole disk.
* 0 means LBA0 is already a FAT32 superfloppy (or probe failed). */
static inline u64 fat32_part_probe(fat32_part_read_fn rd, u32 index) {
u8 sec[512];
u32 i, ent_size;
u64 entries_lba;
if (!rd) return 0;
if (rd(index, 0, 1, sec) == 0 && fat32_part_bpb_ok(sec)) return 0;
if (rd(index, 1, 1, sec) == 0 &&
sec[0] == 'E' && sec[1] == 'F' && sec[2] == 'I' && sec[3] == ' ' &&
sec[4] == 'P' && sec[5] == 'A' && sec[6] == 'R' && sec[7] == 'T') {
entries_lba = fat32_part_r64(sec + 72);
ent_size = (u32)sec[84] | ((u32)sec[85] << 8)
| ((u32)sec[86] << 16) | ((u32)sec[87] << 24);
if (ent_size == 0) ent_size = 128;
if (entries_lba == 0) entries_lba = 2;
if (rd(index, entries_lba, 1, sec) == 0 && ent_size >= 40 && ent_size <= 512) {
for (i = 0; i + ent_size <= 512; i += ent_size) {
u32 j, match = 1;
for (j = 0; j < 16; j++) {
if (sec[i + j] != fat32_part_esp_guid[j]) { match = 0; break; }
}
if (match) return fat32_part_r64(sec + i + 32);
}
}
}
if (rd(index, 2048, 1, sec) == 0 && fat32_part_bpb_ok(sec)) return 2048;
return 0;
}
#endif /* DESHAB_FAT32_PART_H */