Add FAT32 driver, mount app, fix shell cd/path resolution
- FAT32 VFS driver (fat32.h, fat32.c): reads BPB, FAT table, cluster chains, directory entries (8.3 SFN), file read/write, mount via fat32_mount_device() - mount app: writes 'device mountpoint' to /sys/vfs/mount to trigger FAT32 mount from userspace - VFS sysfs mount namespace in kernel.c: handles mount requests via sysfs write to /sys/vfs/mount, delegates to FAT32 driver - Shell cd: validates target directory exists before updating CWD, resolves relative paths (., .., components) to absolute paths - Shell run_command: resolves ARG1 paths relative to CWD so apps like cat and ls receive absolute paths automatically - Fixed FAT32 root directory access: use fs->root_cluster when VFS mount root node has inode=0
This commit is contained in:
95
apps/mount/mount.c
Normal file
95
apps/mount/mount.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file mount.c
|
||||
* @brief Mount a block device as FAT32.
|
||||
*
|
||||
* Writes to /sys/vfs/mount to trigger a kernel-level FAT32 mount.
|
||||
*
|
||||
* Usage: mount <device> <path>
|
||||
* e.g.: mount hdd1mbr1 /mnt
|
||||
*/
|
||||
|
||||
#include "syscalls.h"
|
||||
|
||||
int main(void) {
|
||||
char device[64];
|
||||
char path[128];
|
||||
|
||||
if (getenv("ARG1", device, sizeof(device)) < 0 || device[0] == '\0') {
|
||||
puts("Usage: mount <device> <mountpoint>\n");
|
||||
puts(" e.g.: mount hdd1mbr1 /mnt\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ARG1 contains "device path" — we need to split it.
|
||||
* Actually, the shell currently only passes the first word as ARG1.
|
||||
* Let's accept: mount <device> <path> where ARG1 = "device path" */
|
||||
|
||||
/* Find the space separating device and path */
|
||||
int i = 0;
|
||||
while (device[i] && device[i] != ' ') i++;
|
||||
|
||||
if (device[i] == ' ') {
|
||||
/* ARG1 contains both: "hdd1mbr1 /mnt" */
|
||||
device[i] = '\0';
|
||||
/* Copy path part */
|
||||
int j = i + 1;
|
||||
while (device[j] == ' ') j++;
|
||||
int pi = 0;
|
||||
while (device[j] && pi < 127) {
|
||||
path[pi++] = device[j++];
|
||||
}
|
||||
path[pi] = '\0';
|
||||
} else {
|
||||
/* Only device, no path — default to /mnt */
|
||||
path[0] = '/'; path[1] = 'm'; path[2] = 'n'; path[3] = 't';
|
||||
path[4] = '\0';
|
||||
}
|
||||
|
||||
if (path[0] == '\0') {
|
||||
puts("mount: missing mountpoint, using /mnt\n");
|
||||
path[0] = '/'; path[1] = 'm'; path[2] = 'n'; path[3] = 't';
|
||||
path[4] = '\0';
|
||||
}
|
||||
|
||||
/* Build the mount command: "device path" */
|
||||
char cmd[192];
|
||||
int pos = 0;
|
||||
for (int k = 0; device[k] && pos < 190; k++) cmd[pos++] = device[k];
|
||||
cmd[pos++] = ' ';
|
||||
for (int k = 0; path[k] && pos < 190; k++) cmd[pos++] = path[k];
|
||||
cmd[pos] = '\0';
|
||||
|
||||
/* Open /sys/vfs/mount and write the command */
|
||||
int32_t fd = open("/sys/vfs/mount", 0);
|
||||
if (fd < 0) {
|
||||
puts("mount: cannot open /sys/vfs/mount\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t n = write(fd, cmd, (uint32_t)pos);
|
||||
close(fd);
|
||||
|
||||
if (n < 0) {
|
||||
/* Read the status to show the error */
|
||||
fd = open("/sys/vfs/mounts", 0);
|
||||
if (fd >= 0) {
|
||||
char status[256];
|
||||
int32_t sn = read(fd, status, sizeof(status) - 1);
|
||||
close(fd);
|
||||
if (sn > 0) {
|
||||
status[sn] = '\0';
|
||||
puts(status);
|
||||
}
|
||||
} else {
|
||||
puts("mount: failed\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
puts("mount: ");
|
||||
puts(device);
|
||||
puts(" mounted at ");
|
||||
puts(path);
|
||||
puts("\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user