dospart: recover and convert to mount function
This commit is contained in:
parent
afdf9671a6
commit
996fe55ab0
140
modules/dospart.c
Normal file
140
modules/dospart.c
Normal file
@ -0,0 +1,140 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2014-2018 K. Lange
|
||||
*/
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/module.h>
|
||||
#include <kernel/vfs.h>
|
||||
#include <kernel/printf.h>
|
||||
#include <kernel/tokenize.h>
|
||||
|
||||
#define SECTORSIZE 512
|
||||
|
||||
typedef struct {
|
||||
uint8_t status;
|
||||
uint8_t chs_first_sector[3];
|
||||
uint8_t type;
|
||||
uint8_t chs_last_sector[3];
|
||||
uint32_t lba_first_sector;
|
||||
uint32_t sector_count;
|
||||
} partition_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t boostrap[446];
|
||||
partition_t partitions[4];
|
||||
uint8_t signature[2];
|
||||
} __attribute__((packed)) mbr_t;
|
||||
|
||||
struct dos_partition_entry {
|
||||
fs_node_t * device;
|
||||
partition_t partition;
|
||||
};
|
||||
|
||||
static ssize_t read_part(fs_node_t *node, off_t offset, size_t size, uint8_t *buffer) {
|
||||
struct dos_partition_entry * device = (struct dos_partition_entry *)node->device;
|
||||
|
||||
if ((size_t)offset > device->partition.sector_count * SECTORSIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset + size > device->partition.sector_count * SECTORSIZE) {
|
||||
size = device->partition.sector_count * SECTORSIZE - offset;
|
||||
}
|
||||
|
||||
return read_fs(device->device, offset + device->partition.lba_first_sector * SECTORSIZE, size, buffer);
|
||||
}
|
||||
|
||||
static ssize_t write_part(fs_node_t *node, off_t offset, size_t size, uint8_t *buffer) {
|
||||
struct dos_partition_entry * device = (struct dos_partition_entry *)node->device;
|
||||
|
||||
if ((size_t)offset > device->partition.sector_count * SECTORSIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset + size > device->partition.sector_count * SECTORSIZE) {
|
||||
size = device->partition.sector_count * SECTORSIZE - offset;
|
||||
}
|
||||
|
||||
return write_fs(device->device, offset + device->partition.lba_first_sector * SECTORSIZE, size, buffer);
|
||||
}
|
||||
|
||||
static void open_part(fs_node_t * node, unsigned int flags) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void close_part(fs_node_t * node) {
|
||||
return;
|
||||
}
|
||||
|
||||
static fs_node_t * dospart_device_create(int i, fs_node_t * dev, mbr_t * mbr, int id) {
|
||||
|
||||
vfs_lock(dev);
|
||||
|
||||
struct dos_partition_entry * device = malloc(sizeof(struct dos_partition_entry));
|
||||
memcpy(&device->partition, &mbr->partitions[id], sizeof(partition_t));
|
||||
device->device = dev;
|
||||
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
memset(fnode, 0x00, sizeof(fs_node_t));
|
||||
fnode->inode = 0;
|
||||
snprintf(fnode->name, 20, "dospart%d", i);
|
||||
fnode->device = device;
|
||||
fnode->uid = 0;
|
||||
fnode->gid = 0;
|
||||
fnode->mask = 0660;
|
||||
fnode->length = device->partition.sector_count * SECTORSIZE; /* TODO */
|
||||
fnode->flags = FS_BLOCKDEVICE;
|
||||
fnode->read = read_part;
|
||||
fnode->write = write_part;
|
||||
fnode->open = open_part;
|
||||
fnode->close = close_part;
|
||||
fnode->readdir = NULL;
|
||||
fnode->finddir = NULL;
|
||||
fnode->ioctl = NULL; /* TODO, identify, etc? */
|
||||
return fnode;
|
||||
}
|
||||
|
||||
static fs_node_t * dospart_map(const char * device, const char * mount_path) {
|
||||
char * arg = strdup(device);
|
||||
char * argv[10];
|
||||
tokenize(arg, ",", argv);
|
||||
|
||||
fs_node_t * dev = kopen(argv[0], 0);
|
||||
if (!dev) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbr_t mbr;
|
||||
read_fs(dev, 0, SECTORSIZE, (uint8_t *)&mbr);
|
||||
|
||||
if (mbr.signature[0] == 0x55 && mbr.signature[1] == 0xAA) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (mbr.partitions[i].status & 0x80) {
|
||||
fs_node_t * node = dospart_device_create(i, dev, &mbr, i);
|
||||
char tmp[64];
|
||||
snprintf(tmp, 20, "%s%d", device, i);
|
||||
vfs_mount(tmp, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* VFS_MOUNT_PARTITION_MAPPER_SUCCESS? */
|
||||
return (fs_node_t*)1;
|
||||
}
|
||||
|
||||
static int dospart_initialize(int argc, char * argv[]) {
|
||||
vfs_register("mbr", dospart_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dospart_finalize(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Module metadata = {
|
||||
.name = "dospart",
|
||||
.init = dospart_initialize,
|
||||
.fini = dospart_finalize,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user