https://github.com/ozkl/soso + Much smaller than Linux; builds instantly + Supports graphics - No network support - Doesn't work on a cloud server (yet?)
146 lines
3.5 KiB
C
146 lines
3.5 KiB
C
#include "devfs.h"
|
|
#include "common.h"
|
|
#include "fs.h"
|
|
#include "alloc.h"
|
|
#include "device.h"
|
|
#include "screen.h"
|
|
#include "list.h"
|
|
#include "spinlock.h"
|
|
|
|
static FileSystemNode* gDevRoot = NULL;
|
|
|
|
static List* gDeviceList = NULL;
|
|
static Spinlock gDeviceListLock;
|
|
|
|
static BOOL devfs_open(File *node, uint32 flags);
|
|
static FileSystemDirent *devfs_readdir(FileSystemNode *node, uint32 index);
|
|
static FileSystemNode *devfs_finddir(FileSystemNode *node, char *name);
|
|
|
|
static FileSystemDirent gDirent;
|
|
|
|
void initializeDevFS()
|
|
{
|
|
gDevRoot = kmalloc(sizeof(FileSystemNode));
|
|
memset((uint8*)gDevRoot, 0, sizeof(FileSystemNode));
|
|
|
|
gDevRoot->nodeType = FT_Directory;
|
|
|
|
FileSystemNode* rootFs = getFileSystemRootNode();
|
|
|
|
FileSystemNode* devNode = finddir_fs(rootFs, "dev");
|
|
|
|
if (devNode)
|
|
{
|
|
devNode->nodeType |= FT_MountPoint;
|
|
devNode->mountPoint = gDevRoot;
|
|
gDevRoot->parent = devNode->parent;
|
|
strcpy(gDevRoot->name, devNode->name);
|
|
}
|
|
else
|
|
{
|
|
PANIC("/dev does not exist!");
|
|
}
|
|
|
|
gDevRoot->open = devfs_open;
|
|
gDevRoot->finddir = devfs_finddir;
|
|
gDevRoot->readdir = devfs_readdir;
|
|
|
|
gDeviceList = List_Create();
|
|
Spinlock_Init(&gDeviceListLock);
|
|
}
|
|
|
|
static BOOL devfs_open(File *node, uint32 flags)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
static FileSystemDirent *devfs_readdir(FileSystemNode *node, uint32 index)
|
|
{
|
|
FileSystemDirent * result = NULL;
|
|
|
|
uint32 counter = 0;
|
|
|
|
Spinlock_Lock(&gDeviceListLock);
|
|
|
|
List_Foreach(n, gDeviceList)
|
|
{
|
|
if (index == counter)
|
|
{
|
|
FileSystemNode* deviceNode = (FileSystemNode*)n->data;
|
|
strcpy(gDirent.name, deviceNode->name);
|
|
gDirent.fileType = deviceNode->nodeType;
|
|
gDirent.inode = index;
|
|
result = &gDirent;
|
|
break;
|
|
}
|
|
|
|
++counter;
|
|
}
|
|
Spinlock_Unlock(&gDeviceListLock);
|
|
|
|
return result;
|
|
}
|
|
|
|
static FileSystemNode *devfs_finddir(FileSystemNode *node, char *name)
|
|
{
|
|
FileSystemNode* result = NULL;
|
|
|
|
|
|
Spinlock_Lock(&gDeviceListLock);
|
|
|
|
List_Foreach(n, gDeviceList)
|
|
{
|
|
FileSystemNode* deviceNode = (FileSystemNode*)n->data;
|
|
|
|
if (strcmp(name, deviceNode->name) == 0)
|
|
{
|
|
result = deviceNode;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Spinlock_Unlock(&gDeviceListLock);
|
|
|
|
return result;
|
|
}
|
|
|
|
FileSystemNode* registerDevice(Device* device)
|
|
{
|
|
Spinlock_Lock(&gDeviceListLock);
|
|
|
|
List_Foreach(n, gDeviceList)
|
|
{
|
|
FileSystemNode* deviceNode = (FileSystemNode*)n->data;
|
|
|
|
if (strcmp(device->name, deviceNode->name) == 0)
|
|
{
|
|
//There is already a device with the same name
|
|
Spinlock_Unlock(&gDeviceListLock);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
FileSystemNode* deviceNode = (FileSystemNode*)kmalloc(sizeof(FileSystemNode));
|
|
memset((uint8*)deviceNode, 0, sizeof(FileSystemNode));
|
|
strcpy(deviceNode->name, device->name);
|
|
deviceNode->nodeType = device->deviceType;
|
|
deviceNode->open = device->open;
|
|
deviceNode->close = device->close;
|
|
deviceNode->readBlock = device->readBlock;
|
|
deviceNode->writeBlock = device->writeBlock;
|
|
deviceNode->read = device->read;
|
|
deviceNode->write = device->write;
|
|
deviceNode->ioctl = device->ioctl;
|
|
deviceNode->ftruncate = device->ftruncate;
|
|
deviceNode->mmap = device->mmap;
|
|
deviceNode->munmap = device->munmap;
|
|
deviceNode->privateNodeData = device->privateData;
|
|
deviceNode->parent = gDevRoot;
|
|
|
|
List_Append(gDeviceList, deviceNode);
|
|
|
|
Spinlock_Unlock(&gDeviceListLock);
|
|
|
|
return deviceNode;
|
|
}
|