Add filesystem driver
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import { dwordin, dwordout } from "../../../lib/libts/dword";
|
import { dwordin, dwordout } from "../../../lib/libts/dword";
|
||||||
import { portin, portout } from "../../../lib/libts/port";
|
import { portin, portout } from "../../../lib/libts/port";
|
||||||
import { Logger } from "../../../lib/libstd/logger/logger.kmod";
|
import { Logger } from "../../../lib/libstd/logger/logger.kmod";
|
||||||
|
import { sysfs_mkdir, sysfs_writeFile } from "../../filesystem/sysfs";
|
||||||
|
import { Path } from "../../../lib/libstd/path";
|
||||||
|
|
||||||
const KDRIVER_PCI_CONFIG_ADDR = 0xcf8;
|
const KDRIVER_PCI_CONFIG_ADDR = 0xcf8;
|
||||||
const KDRIVER_PCI_CONFIG_DATA = 0xcfc;
|
const KDRIVER_PCI_CONFIG_DATA = 0xcfc;
|
||||||
@@ -37,13 +39,11 @@ export function kdriver_dev_pci_checkDevice(
|
|||||||
const classCode = kdriver_dev_pci_getClassCode(bus, device, func);
|
const classCode = kdriver_dev_pci_getClassCode(bus, device, func);
|
||||||
const subclass = kdriver_dev_pci_getSubclass(bus, device, func);
|
const subclass = kdriver_dev_pci_getSubclass(bus, device, func);
|
||||||
|
|
||||||
|
const filename = bus + ":" + device + ":" + func;
|
||||||
|
|
||||||
Logger.log(
|
Logger.log(
|
||||||
"[PCI] Found device pci:" +
|
"[PCI] Found device pci:" +
|
||||||
bus +
|
filename +
|
||||||
":" +
|
|
||||||
device +
|
|
||||||
":" +
|
|
||||||
func +
|
|
||||||
" (vendor:" +
|
" (vendor:" +
|
||||||
vendorId.toString(16) +
|
vendorId.toString(16) +
|
||||||
", device:" +
|
", device:" +
|
||||||
@@ -54,6 +54,14 @@ export function kdriver_dev_pci_checkDevice(
|
|||||||
subclass.toString(16) +
|
subclass.toString(16) +
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const dirname = Path.join("/pci", filename);
|
||||||
|
|
||||||
|
sysfs_mkdir(dirname);
|
||||||
|
sysfs_writeFile(Path.join(dirname, "vendor"), vendorId);
|
||||||
|
sysfs_writeFile(Path.join(dirname, "device"), deviceId);
|
||||||
|
sysfs_writeFile(Path.join(dirname, "class"), classCode);
|
||||||
|
sysfs_writeFile(Path.join(dirname, "subclass"), subclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function kdriver_dev_pci_getDeviceId(
|
export function kdriver_dev_pci_getDeviceId(
|
||||||
|
|||||||
138
src/os/src/kernel/filesystem/sysfs.ts
Normal file
138
src/os/src/kernel/filesystem/sysfs.ts
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
import { Logger } from "../../lib/libstd/logger/logger.kmod";
|
||||||
|
import { Path } from "../../lib/libstd/path";
|
||||||
|
import type {
|
||||||
|
KFilesystemDriver,
|
||||||
|
KFilesystemEntity,
|
||||||
|
KFilesystemMemdata,
|
||||||
|
KFilesystemStat,
|
||||||
|
} from "../../types/filesystem/fs";
|
||||||
|
|
||||||
|
const sysfs_data: KFilesystemMemdata = [];
|
||||||
|
|
||||||
|
export function sysfs_driver(): KFilesystemDriver {
|
||||||
|
return {
|
||||||
|
id: "sysfs",
|
||||||
|
init: sysfs_init,
|
||||||
|
listDir(path: string): KFilesystemEntity[] | null {
|
||||||
|
return sysfs_listDir(path);
|
||||||
|
},
|
||||||
|
readFile(path: string): unknown {
|
||||||
|
return sysfs_readFile(path);
|
||||||
|
},
|
||||||
|
writeFile(path: string, content: unknown): void {
|
||||||
|
throw new Error("Cannot write to sysfs files.");
|
||||||
|
},
|
||||||
|
createFile(path: string, content: unknown): void {
|
||||||
|
throw new Error("Cannot create files in sysfs.");
|
||||||
|
},
|
||||||
|
mkdir(path: string): void {
|
||||||
|
throw new Error("Cannot create directories in sysfs.");
|
||||||
|
},
|
||||||
|
stat(path: string): KFilesystemStat | null {
|
||||||
|
return sysfs_statEntity(path);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_init(): void {
|
||||||
|
sysfs_data.push({
|
||||||
|
name: "root",
|
||||||
|
path: "/",
|
||||||
|
type: "folder",
|
||||||
|
size: 0,
|
||||||
|
contents: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
sysfs_mkdir("/pci");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_getEntity(path: string): KFilesystemEntity | null {
|
||||||
|
for (let i = 0; i < sysfs_data.length; i++) {
|
||||||
|
const entity = sysfs_data[i]!;
|
||||||
|
|
||||||
|
if (entity.path === path) return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_statEntity(path: string): KFilesystemStat | null {
|
||||||
|
const entity = sysfs_getEntity(path);
|
||||||
|
if (!entity) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: entity.name,
|
||||||
|
type: entity.type,
|
||||||
|
size: entity.size,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_mkdir(path: string): void {
|
||||||
|
if (sysfs_getEntity(path)) return;
|
||||||
|
|
||||||
|
const parent = Path.dirname(path);
|
||||||
|
if (!sysfs_getEntity(parent)) return;
|
||||||
|
|
||||||
|
sysfs_data.push({
|
||||||
|
name: Path.filename(path),
|
||||||
|
path,
|
||||||
|
type: "folder",
|
||||||
|
size: 0,
|
||||||
|
contents: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_createFile(path: string, content: unknown): void {
|
||||||
|
if (sysfs_getEntity(path)) return;
|
||||||
|
|
||||||
|
const parent = Path.dirname(path);
|
||||||
|
if (!sysfs_getEntity(parent)) return;
|
||||||
|
|
||||||
|
const size = String(content).length;
|
||||||
|
|
||||||
|
sysfs_data.push({
|
||||||
|
name: Path.filename(path),
|
||||||
|
path,
|
||||||
|
type: "file",
|
||||||
|
size,
|
||||||
|
contents: content,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_writeFile(path: string, content: unknown): void {
|
||||||
|
const entity = sysfs_getEntity(path);
|
||||||
|
if (!entity) return sysfs_createFile(path, content);
|
||||||
|
|
||||||
|
if (entity.type !== "file") return;
|
||||||
|
|
||||||
|
entity.contents = content;
|
||||||
|
entity.size = String(content).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_readFile(path: string): unknown {
|
||||||
|
const entity = sysfs_getEntity(path);
|
||||||
|
if (!entity) return null;
|
||||||
|
|
||||||
|
if (entity.type !== "file") return null;
|
||||||
|
|
||||||
|
return entity.contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sysfs_listDir(path: string): KFilesystemEntity[] | null {
|
||||||
|
const entity = sysfs_getEntity(path);
|
||||||
|
if (!entity) return null;
|
||||||
|
|
||||||
|
if (entity.type !== "folder") return null;
|
||||||
|
|
||||||
|
const contents: KFilesystemEntity[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < sysfs_data.length; i++) {
|
||||||
|
const e = sysfs_data[i]!;
|
||||||
|
|
||||||
|
if (Path.dirname(e.path) === path) {
|
||||||
|
contents.push(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
@@ -7,10 +7,16 @@ import {
|
|||||||
kdriver_etc_serial_read,
|
kdriver_etc_serial_read,
|
||||||
kdriver_etc_serial_transmit,
|
kdriver_etc_serial_transmit,
|
||||||
} from "./drivers/etc/serial";
|
} from "./drivers/etc/serial";
|
||||||
|
import { sysfs_driver, sysfs_readFile } from "./filesystem/sysfs";
|
||||||
import {
|
import {
|
||||||
kmod_drivers_init,
|
kmod_drivers_init,
|
||||||
kmod_drivers_register,
|
kmod_drivers_register,
|
||||||
} from "./modules/drivers/drivers.kmod";
|
} from "./modules/drivers/drivers.kmod";
|
||||||
|
import {
|
||||||
|
kmod_filesystem_init,
|
||||||
|
kmod_filesystem_mount,
|
||||||
|
kmod_filesystem_readFile,
|
||||||
|
} from "./modules/filesystem/filesystem.kmod";
|
||||||
import {
|
import {
|
||||||
kmod_graphics_vga_clear,
|
kmod_graphics_vga_clear,
|
||||||
kmod_graphics_vga_init,
|
kmod_graphics_vga_init,
|
||||||
@@ -23,11 +29,18 @@ export function kmain() {
|
|||||||
kmod_drivers_register();
|
kmod_drivers_register();
|
||||||
Logger.log("[Kernel] Drivers initialized.");
|
Logger.log("[Kernel] Drivers initialized.");
|
||||||
|
|
||||||
Logger.log("[Kernel] Initializing PCI...");
|
Logger.log("[Kernel] Initializing filesystem module...");
|
||||||
|
kmod_filesystem_init();
|
||||||
|
kmod_filesystem_mount("/sys", sysfs_driver);
|
||||||
|
|
||||||
|
Logger.log("[Kernel] Initializing PCI devices...");
|
||||||
kdriver_dev_pci_detectDevices();
|
kdriver_dev_pci_detectDevices();
|
||||||
|
|
||||||
Logger.log("[Kernel] Initializing VGA module...");
|
Logger.log("[Kernel] Initializing VGA module...");
|
||||||
kmod_graphics_vga_init();
|
kmod_graphics_vga_init();
|
||||||
kmod_graphics_vga_pushLine("[Kernel] Kernel initialized successfully.");
|
kmod_graphics_vga_pushLine("[Kernel] Kernel initialized successfully.");
|
||||||
kmod_graphics_vga_pushLine("Current date: " + getDate().toDateString());
|
kmod_graphics_vga_pushLine("Current date: " + getDate().toDateString());
|
||||||
|
kmod_graphics_vga_pushLine(
|
||||||
|
Number(kmod_filesystem_readFile("/sys/pci/0:1:0/vendor")).toString(16)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
111
src/os/src/kernel/modules/filesystem/filesystem.kmod.ts
Normal file
111
src/os/src/kernel/modules/filesystem/filesystem.kmod.ts
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import { Logger } from "../../../lib/libstd/logger/logger.kmod";
|
||||||
|
import type {
|
||||||
|
KFilesystemDriver,
|
||||||
|
KFilesystemEntity,
|
||||||
|
KFilesystemMount,
|
||||||
|
KFilesystemMountdata,
|
||||||
|
KFilesystemStat,
|
||||||
|
} from "../../../types/filesystem/fs";
|
||||||
|
|
||||||
|
const kmod_filesystem_data: KFilesystemMountdata = [];
|
||||||
|
|
||||||
|
export function kmod_filesystem_init(): void {}
|
||||||
|
|
||||||
|
export function kmod_filesystem_mount(
|
||||||
|
mpoint: string,
|
||||||
|
drv: () => KFilesystemDriver
|
||||||
|
): void {
|
||||||
|
const driver = drv();
|
||||||
|
|
||||||
|
driver.init();
|
||||||
|
|
||||||
|
kmod_filesystem_data.push({
|
||||||
|
mountpoint: mpoint,
|
||||||
|
driver: driver,
|
||||||
|
});
|
||||||
|
|
||||||
|
Logger.log("[Filesystem] Mounted " + driver.id + " at " + mpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_findMount(p: string): KFilesystemMount | null {
|
||||||
|
for (let i = 0; i < kmod_filesystem_data.length; i++) {
|
||||||
|
const mount = kmod_filesystem_data[i]!;
|
||||||
|
|
||||||
|
if (p.startsWith(mount.mountpoint)) {
|
||||||
|
return mount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_stripMountpoint(
|
||||||
|
mount: KFilesystemMount,
|
||||||
|
p: string
|
||||||
|
): string {
|
||||||
|
if (mount.mountpoint === "/") return p;
|
||||||
|
|
||||||
|
return p.slice(mount.mountpoint.length) || "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_listDir(
|
||||||
|
path: string
|
||||||
|
): KFilesystemEntity[] | null {
|
||||||
|
const mount = kmod_filesystem_findMount(path);
|
||||||
|
if (!mount) return null;
|
||||||
|
|
||||||
|
const strippedPath = kmod_filesystem_stripMountpoint(mount, path);
|
||||||
|
|
||||||
|
return mount.driver.listDir(strippedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_readFile(path: string): unknown {
|
||||||
|
const mount = kmod_filesystem_findMount(path);
|
||||||
|
if (!mount) return null;
|
||||||
|
|
||||||
|
const strippedPath = kmod_filesystem_stripMountpoint(mount, path);
|
||||||
|
|
||||||
|
return mount.driver.readFile(strippedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_writeFile(
|
||||||
|
path: string,
|
||||||
|
content: unknown
|
||||||
|
): void {
|
||||||
|
const mount = kmod_filesystem_findMount(path);
|
||||||
|
if (!mount) return;
|
||||||
|
|
||||||
|
const strippedPath = kmod_filesystem_stripMountpoint(mount, path);
|
||||||
|
|
||||||
|
mount.driver.writeFile(strippedPath, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_createFile(
|
||||||
|
path: string,
|
||||||
|
content: unknown
|
||||||
|
): void {
|
||||||
|
const mount = kmod_filesystem_findMount(path);
|
||||||
|
if (!mount) return;
|
||||||
|
|
||||||
|
const strippedPath = kmod_filesystem_stripMountpoint(mount, path);
|
||||||
|
|
||||||
|
mount.driver.createFile(strippedPath, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_mkdir(path: string): void {
|
||||||
|
const mount = kmod_filesystem_findMount(path);
|
||||||
|
if (!mount) return;
|
||||||
|
|
||||||
|
const strippedPath = kmod_filesystem_stripMountpoint(mount, path);
|
||||||
|
|
||||||
|
mount.driver.mkdir(strippedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_filesystem_stat(path: string): KFilesystemStat | null {
|
||||||
|
const mount = kmod_filesystem_findMount(path);
|
||||||
|
if (!mount) return null;
|
||||||
|
|
||||||
|
const strippedPath = kmod_filesystem_stripMountpoint(mount, path);
|
||||||
|
|
||||||
|
return mount.driver.stat(strippedPath);
|
||||||
|
}
|
||||||
30
src/os/src/lib/libstd/path.ts
Normal file
30
src/os/src/lib/libstd/path.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
export const Path = {
|
||||||
|
dirname(p: string): string {
|
||||||
|
const parts = p.split("/");
|
||||||
|
|
||||||
|
parts.pop();
|
||||||
|
|
||||||
|
if (parts.length <= 1) return "/";
|
||||||
|
|
||||||
|
return parts.join("/");
|
||||||
|
},
|
||||||
|
filename(p: string): string {
|
||||||
|
const parts = p.split("/");
|
||||||
|
|
||||||
|
const n = parts.pop();
|
||||||
|
|
||||||
|
if (!n) return "";
|
||||||
|
return n;
|
||||||
|
},
|
||||||
|
join(p1: string, p2: string): string {
|
||||||
|
if (p1.endsWith("/")) {
|
||||||
|
p1 = p1.slice(0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p2.startsWith("/")) {
|
||||||
|
p2 = p2.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p1 + "/" + p2;
|
||||||
|
},
|
||||||
|
};
|
||||||
33
src/os/src/types/filesystem/fs.ts
Normal file
33
src/os/src/types/filesystem/fs.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
export type KFilesystemMountdata = KFilesystemMount[];
|
||||||
|
|
||||||
|
export type KFilesystemMount = {
|
||||||
|
mountpoint: string;
|
||||||
|
driver: KFilesystemDriver;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type KFilesystemDriver = {
|
||||||
|
id: string;
|
||||||
|
init: () => void;
|
||||||
|
listDir(path: string): KFilesystemEntity[] | null;
|
||||||
|
readFile(path: string): unknown;
|
||||||
|
writeFile(path: string, content: unknown): void;
|
||||||
|
createFile(path: string, content: unknown): void;
|
||||||
|
mkdir(path: string): void;
|
||||||
|
stat(path: string): KFilesystemStat | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type KFilesystemMemdata = KFilesystemEntity[];
|
||||||
|
|
||||||
|
export type KFilesystemEntity = {
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
size: number;
|
||||||
|
contents: unknown;
|
||||||
|
type: "file" | "folder";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type KFilesystemStat = {
|
||||||
|
name: string;
|
||||||
|
type: "file" | "folder";
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user