1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include <assert.h>
#include <drivers/keyboard.h>
#include <drivers/serial.h>
#include <fs/devfs.h>
#include <fs/vfs.h>
#include <random.h>
devfs_file files[20];
int num_files = 0;
vfs_inode_t *devfs_add_file(
char *path, int (*read)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd),
int (*write)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd),
vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, vfs_fd_t *fd),
int (*has_data)(vfs_inode_t *inode), int (*can_write)(vfs_inode_t *inode),
int type) {
files[num_files].name = copy_and_allocate_string(path);
vfs_inode_t *i = kcalloc(1, sizeof(vfs_inode_t));
files[num_files].inode = i;
i->type = type;
i->read = read;
i->write = write;
i->close = NULL;
i->get_vm_object = get_vm_object;
i->_has_data = has_data;
i->_can_write = can_write;
i->is_open = 1;
num_files++;
return i;
}
vfs_inode_t *devfs_open(const char *file) {
for (int i = 0; i < num_files; i++) {
if (isequal_n(files[i].name, file, strlen(files[i].name))) {
// FIXME: Temporary hack
vfs_inode_t *r = kmalloc(sizeof(vfs_inode_t));
if (!r) {
return NULL; // TODO: Give some error condition
}
memcpy(r, files[i].inode, sizeof(vfs_inode_t));
return r;
}
}
return NULL;
}
int devfs_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
return fd->inode->read(buffer, offset, len, fd);
}
int devfs_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
return fd->inode->write(buffer, offset, len, fd);
}
vfs_vm_object_t *devfs_get_vm_object(u64 length, u64 offset, vfs_fd_t *fd) {
return fd->inode->get_vm_object(length, offset, fd);
}
int stdout_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
(void)offset;
(void)fd;
int rc = len;
for (; len--;) {
write_serial(*buffer++);
}
return rc;
}
int serial_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
(void)offset;
(void)fd;
int rc = len;
for (; len--;) {
write_serial(*buffer++);
}
return rc;
}
int always_has_data(vfs_inode_t *inode) {
(void)inode;
return 1;
}
int always_can_write(vfs_inode_t *inode) {
(void)inode;
return 1;
}
void add_serial(void) {
devfs_add_file("/serial", NULL, serial_write, NULL, NULL, always_can_write,
FS_TYPE_CHAR_DEVICE);
}
void add_stdout(void) {
devfs_add_file("/stdout", NULL, stdout_write, NULL, NULL, always_can_write,
FS_TYPE_CHAR_DEVICE);
}
vfs_inode_t *devfs_mount(void) {
vfs_inode_t *root = kcalloc(1, sizeof(vfs_inode_t));
root->open = devfs_open;
root->read = devfs_read;
root->write = devfs_write;
root->close = NULL;
return root;
}
|