Skip to content

Commit 10941b4

Browse files
authored
Merge pull request #105 from KaiNorberg/develop
feat(kernel:sysfs): add sysfs, move acpi to sysfs, add filesystem int…
2 parents d388f8e + d734f47 commit 10941b4

20 files changed

Lines changed: 766 additions & 77 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ BOXES = $(shell find src/boxes/ -name "*.mk")
88
PROGRAMS = $(shell find src/programs/ -name "*.mk")
99
MODULES = $(shell find src/modules/ -name "*.mk")
1010

11-
ROOT_DIRS = acpi base base/bin base/lib base/include base/data box cfg dev efi efi/boot kernel kernel/modules kernel/modules/$(VERSION_STRING) net proc sbin tmp
11+
ROOT_DIRS = acpi base base/bin base/lib base/include base/data box cfg dev efi efi/boot kernel kernel/modules kernel/modules/$(VERSION_STRING) net proc sbin sys tmp
1212

1313
# Programs to copy to /sbin
1414
SBIN_PROGRAMS = init boxd

include/kernel/fs/devfs.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ typedef struct superblock_ops superblock_ops_t;
1515
* @ingroup kernel_fs
1616
* @defgroup kernel_fs_devfs Device Filesystem
1717
*
18+
* The devfs is a virtual filesystem that provides access to devices and resources.
19+
*
20+
* @{
1821
*/
1922

2023
/**
@@ -30,8 +33,6 @@ void devfs_init(void);
3033
/**
3134
* @brief Create a new directory inside a mounted devfs instance.
3235
*
33-
* Used to, for example, create a new directory for a device or resource inside `/dev` or `/proc`.
34-
*
3536
* @param parent The parent directory, if `NULL` then the root is used.
3637
* @param name The name of the new directory.
3738
* @param inodeOps The inode operations for the new directory, can be `NULL`.
@@ -43,8 +44,6 @@ dentry_t* devfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* i
4344
/**
4445
* @brief Create a new file inside a mounted devfs instance.
4546
*
46-
* Used to, for example, create a new file for a device or resource inside `/dev` or `/proc`.
47-
*
4847
* @param parent The parent directory, if `NULL` then the root is used.
4948
* @param name The name of the new file.
5049
* @param inodeOps The inode operations for the new file, can be `NULL`.

include/kernel/fs/filesystem.h

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,29 @@
1818

1919
/**
2020
* @brief Filesystem interface.
21-
* @defgroup kernel_fs_filesystem Filesystem
21+
* @defgroup kernel_fs_filesystem Filesystem.
2222
* @ingroup kernel_fs
2323
*
24+
* The filesystem interface represents a filesystem type, e.g. fat32, tmpfs, devfs, etc. Each filesystem is exposed in a
25+
* directory within the `fs` sysfs directory named after the filesystem.
26+
*
27+
* The directory itself can be used to mount instances of that filesystem type.
28+
*
29+
* Within each filesystem directory are readable files representing each mounted instance of that filesystem type, named
30+
* after the superblock ID, containing the following information:
31+
*
32+
* ```
33+
* id: %llu
34+
* block_size: %llu
35+
* max_file_size: %llu
36+
*
37+
* ```
38+
*
39+
* Where the `id` is the superblock ID, `block_size` is the block size of the superblock, and `max_file_size` is the
40+
* maximum size of a file on this superblock.
41+
*
42+
* @see kernel_fs_sysfs
43+
*
2444
* @{
2545
*/
2646

@@ -31,13 +51,21 @@
3151
*/
3252
typedef struct filesystem
3353
{
54+
list_entry_t entry; ///< Used internally.
3455
map_entry_t mapEntry; ///< Used internally.
3556
list_t superblocks; ///< Used internally.
3657
rwlock_t lock; ///< Used internally.
3758
const char* name;
3859
dentry_t* (*mount)(filesystem_t* fs, block_device_t* device, void* private);
3960
} filesystem_t;
4061

62+
/**
63+
* @brief Exposes the sysfs `fs` directory.
64+
*
65+
* Must be called before `filesystem_get_by_path()` can be used.
66+
*/
67+
void filesystem_expose(void);
68+
4169
/**
4270
* @brief Registers a filesystem.
4371
*
@@ -61,6 +89,20 @@ void filesystem_unregister(filesystem_t* fs);
6189
* @param name The name of the filesystem.
6290
* @return On success, the filesystem. On failure, returns `NULL`.
6391
*/
64-
filesystem_t* filesystem_get(const char* name);
92+
filesystem_t* filesystem_get_by_name(const char* name);
93+
94+
/**
95+
* @brief Gets a filesystem by path.
96+
*
97+
* The path should point to a directory in the `fs` sysfs directory.
98+
*
99+
* @param path The path to check.
100+
* @param process The process whose namespace to use.
101+
* @return On success, the filesystem. On failure, returns `NULL` and `errno` is set to:
102+
* - `ENOENT`: The path does not exist.
103+
* - `ENOMEM`: Out of memory.
104+
* - `EINVAL`: The path is not a directory in the `fs` sysfs directory.
105+
*/
106+
filesystem_t* filesystem_get_by_path(const char* path, process_t* process);
65107

66108
/** @} */

include/kernel/fs/namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ bool namespace_traverse(namespace_t* ns, path_t* path);
113113
*
114114
* @param ns The namespace containing the namespace to mount to.
115115
* @param target The target path to mount to, can be `NULL` to mount to root.
116-
* @param fsName The filesystem name.
116+
* @param fs The filesystem to mount.
117117
* @param deviceName The device name, or `NULL` for no device.
118118
* @param flags Mount flags.
119119
* @param mode The mode specifying permissions and mount behaviour.
@@ -128,7 +128,7 @@ bool namespace_traverse(namespace_t* ns, path_t* path);
128128
* - `ENOENT`: The root does not exist or the target is negative.
129129
* - Other errors as returned by the filesystem's `mount()` function or `mount_new()`.
130130
*/
131-
mount_t* namespace_mount(namespace_t* ns, path_t* target, const char* fsName, const char* deviceName, mode_t mode,
131+
mount_t* namespace_mount(namespace_t* ns, path_t* target, filesystem_t* fs, const char* deviceName, mode_t mode,
132132
void* private);
133133

134134
/**

include/kernel/fs/procfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@
158158
*
159159
* Mounts a filesystem at the specified mountpoint in the process's namespace, optionally with a device.
160160
*
161+
* The filesystem should be specified as a path to a directory in the `fs` sysfs directory.
162+
*
161163
* @see kernel_fs_path for information on path flags.
162164
*
163165
* ### touch <path>

include/kernel/fs/sysfs.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#pragma once
2+
3+
#include <kernel/fs/dentry.h>
4+
#include <kernel/fs/inode.h>
5+
#include <sys/io.h>
6+
7+
typedef struct file file_t;
8+
typedef struct file_ops file_ops_t;
9+
10+
typedef struct superblock superblock_t;
11+
typedef struct superblock_ops superblock_ops_t;
12+
13+
/**
14+
* @brief System Filesystem.
15+
* @ingroup kernel_fs
16+
* @defgroup kernel_fs_sysfs System Filesystem
17+
*
18+
* The sysfs is a virtual filesystem that provides information about devices and kernel modules.
19+
*
20+
* @{
21+
*/
22+
23+
/**
24+
* @brief The name of the system filesystem.
25+
*/
26+
#define SYSFS_NAME "sysfs"
27+
28+
/**
29+
* @brief Initializes the sysfs and mount an instance at `/sys`.
30+
*
31+
* The System Filesystem is one of the few filesystem that will be mounted automatically by the kernel, this is
32+
* necessary as otherwise user space would be unable to access the `fs` sysfs directory and thus unable to mount any
33+
* filesystem.
34+
*
35+
*/
36+
void sysfs_init(void);
37+
38+
/**
39+
* @brief Create a new directory inside a mounted sysfs instance.
40+
*
41+
* @param parent The parent directory, if `NULL` then the root is used.
42+
* @param name The name of the new directory.
43+
* @param inodeOps The inode operations for the new directory, can be `NULL`.
44+
* @param private Private data to store in the inode of the new directory, can be `NULL`.
45+
* @return On success, the new sysfs directory. On failure, `NULL` and `errno` is set.
46+
*/
47+
dentry_t* sysfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* private);
48+
49+
/**
50+
* @brief Create a new file inside a mounted sysfs instance.
51+
*
52+
* @param parent The parent directory, if `NULL` then the root is used.
53+
* @param name The name of the new file.
54+
* @param inodeOps The inode operations for the new file, can be `NULL`.
55+
* @param fileOps The file operations for the new file, can be `NULL`.
56+
* @param private Private data to store in the inode of the new file, can be `NULL`.
57+
* @return On success, the new sysfs file. On failure, `NULL` and `errno` is set.
58+
*/
59+
dentry_t* sysfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, const file_ops_t* fileOps,
60+
void* private);
61+
62+
/**
63+
* @brief Create a new symbolic link inside a mounted sysfs instance.
64+
*
65+
* @param parent The parent directory, if `NULL` then the root is used.
66+
* @param name The name of the new symbolic link.
67+
* @param inodeOps The inode operations for the new symbolic link.
68+
* @param private Private data to store in the inode of the new symbolic link, can be `NULL`.
69+
* @return On success, the new sysfs symbolic link. On failure, `NULL` and `errno` is set.
70+
*/
71+
dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* private);
72+
73+
/**
74+
* @brief Descriptor for batch file creation.
75+
* @struct sysfs_file_desc_t
76+
*/
77+
typedef struct sysfs_file_desc
78+
{
79+
const char* name; ///< Name of the file, `NULL` marks end of array.
80+
const inode_ops_t* inodeOps; ///< Inode operations, can be `NULL`.
81+
const file_ops_t* fileOps; ///< File operations, can be `NULL`.
82+
void* private; ///< Private data to store in the inode of the file.
83+
} sysfs_file_desc_t;
84+
85+
/**
86+
* @brief Create multiple files in a sysfs directory.
87+
*
88+
* @param out Output list to store created dentries, can be `NULL`. The dentries use the `otherEntry` list entry.
89+
* @param parent The parent directory, if `NULL` then the root is used.
90+
* @param descs Array of file descriptors, terminated by an entry with `name == NULL`.
91+
* @return On success, the number of files created. On failure, `ERR` and `errno` is set.
92+
*/
93+
uint64_t sysfs_files_new(list_t* out, dentry_t* parent, const sysfs_file_desc_t* descs);
94+
95+
/**
96+
* @brief Free all files in a list created by `sysfs_files_new()`.
97+
*
98+
* @param files The list of files to free.
99+
*/
100+
void sysfs_files_free(list_t* files);
101+
102+
/** @} */

include/libstd/sys/io.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ uint64_t bind(const char* mountpoint, fd_t source);
560560
* @brief System call for mounting a filesystem.
561561
*
562562
* @param mountpoint The target path to mount to.
563-
* @param fs The filesystem name.
563+
* @param fs The path to the desired filesystem in the `fs` sysfs directory.
564564
* @param device The device name, or `NULL` for no device.
565565
* @return On success, `0`. On failure, `ERR` and `errno` is set.
566566
*/

root/box/terminal/manifest

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ PATH = /base/bin
2222
/dev:rw = /dev
2323
/net:rw = /net
2424
/proc:rw = /proc
25+
/sys:rw = /sys
26+
/tmp:rwL = /tmp

0 commit comments

Comments
 (0)