feat: Vfs and Ext2 support. Code style/attribute improvements

Added VFS and Ext2 support.
Optimized attributes of methods to improve code highlighting.
Printf attribute, malloc attribute, etc.
This commit is contained in:
2021-10-06 21:45:15 +02:00
parent 073051c99e
commit 03f0ec6f88
24 changed files with 1322 additions and 90 deletions

View File

@@ -7,7 +7,7 @@
// retrieved from https://github.com/blanham/liballoc
#include <sys/types.h>
void *malloc(size_t);
void __attribute__((assume_aligned (16), alloc_size (1), malloc)) *malloc(size_t);
void *realloc(void *, size_t);

View File

@@ -9,6 +9,8 @@
#include <sys/types.h>
#include <myke/driver.h>
#define BLOCK_DEV_LBA_SIZE 512
#define BLOCK_DEV_ACCESS_OK 0
#define BLOCK_DEV_ACCESS_ERR 1
@@ -27,21 +29,21 @@
typedef struct block_device block_device_t;
typedef uint8_t (*block_device_driver_check_device)(const block_device_t *device, uint8_t *first_sector);
typedef uint8_t (*block_device_driver_check_device)(block_device_t *device);
typedef uint8_t (*block_device_driver_free)(const block_device_t *device);
typedef uint8_t (*block_device_driver_free)(block_device_t *device);
typedef uint8_t (*block_device_access)(const block_device_t *device, uint8_t direction, uint32_t lba, uint8_t sectors,
void *target);
struct block_dev_driver {
typedef struct block_dev_driver {
char name[16];
struct {
uint8_t partitioning: 1;
} flags;
block_device_driver_check_device check_device;
block_device_driver_free free_device;
} __attribute__((__aligned__(STRUCT_ALIGNMENT)));
} __attribute__((__aligned__(STRUCT_ALIGNMENT))) block_dev_driver_t;
#define BLOCK_DEV_DRIVER(order) GENERIC_DRIVER(block_dev_driver, order)
@@ -59,6 +61,7 @@ struct block_device {
block_device_access access;
struct block_dev_driver *driver;
void *device_info; // pointer to driver defined structure
void *driver_info; // pointer to driver defined structure
// todo device info
};
@@ -66,8 +69,8 @@ uint8_t block_dev_register(block_device_t *device);
void block_dev_free(block_device_t *device);
void *block_dev_mount(const char *device, const char *driver_name);
void block_dev_print_info();
bool block_dev_mount(char *identifier, char *driver);
#endif //NEW_KERNEL_BLOCKDEV_H

223
include/myke/vfs/lfs/ext2.h Normal file
View File

@@ -0,0 +1,223 @@
//
// Created by rick on 18-09-21.
//
#ifndef NEW_KERNEL_EXT2_H
#define NEW_KERNEL_EXT2_H
#include <sys/types.h>
#include <attributes.h>
#define EXT2_SIGNATURE 0xEF53
#define EXT2_SB_ADDR 1024
#define EXT2_SB_SIZE 1024
#define EXT2_BGD_START_ADDR (EXT2_SB_ADDR + EXT2_SB_SIZE)
#define EXT2_DEFAULT_RESERVED_INODES 11
#define EXT2_DEFAULT_INODE_SIZE 128
#define EXT2_ROOT_INODE 2
typedef struct ext2_sb {
uint32_t total_inodes;
uint32_t total_blocks;
uint32_t num_reserved_su;
uint32_t unallocated_blocks;
uint32_t unallocated_inodes;
uint32_t no_blocks_with_sb;
uint32_t block_size;
uint32_t fragment_size;
uint32_t no_blocks_per_group;
uint32_t no_fragments_per_group;
uint32_t no_inodes_per_group;
uint32_t last_mounted;
uint32_t last_written;
uint16_t no_mounted_since_fschk;
uint16_t max_no_mounted_since_fschk;
uint16_t ext2_signature;
uint16_t fs_state;
uint16_t error_action;
uint16_t minor_version;
uint32_t last_fschk;
uint32_t interval_fschk;
uint32_t os_id;
uint32_t major_version;
uint16_t uid_reserved;
uint16_t gid_reserved;
// below extended fields
uint32_t first_nor_reserved_inode;
uint16_t size_inode;
uint16_t owner_bg;
uint32_t features_optional;
uint32_t features_required;
uint32_t features_ro;
uint8_t fs_id[16];
char fs_name[16];
char last_mounted_path[64];
uint32_t compression_alg;
uint8_t preallocate_files;
uint8_t preallocate_dirs;
uint16_t: 16; // unused
uint8_t journal_id[16];
uint32_t journal_inode;
uint32_t journal_device;
uint32_t head_of_orphan_inode_list;
} att_packed ext2_sb_t;
enum {
EXT2_FS_STATE_CLEAN = 1,
EXT2_FS_STATE_ERROR = 2,
};
enum {
EXT2_ERROR_ACTION_IGNORE = 1,
EXT2_ERROR_ACTION_REMOUNT_RO = 2,
EXT2_ERROR_ACTION_PANIC = 3,
};
enum {
EXT2_OS_ID_LINUX = 0,
EXT2_OS_ID_GNU_HURD = 1,
EXT2_OS_ID_MASIX = 2,
EXT2_OS_ID_FREE_BSD = 3,
EXT2_OS_ID_LITES = 4,
};
enum {
EXT2_FEATURE_OPTIONAL_PREALLOCATE = 0x01,
EXT2_FEATURE_OPTIONAL_AFS_SERVER_INODE = 0x02,
EXT2_FEATURE_OPTIONAL_HAS_JOURNAL = 0x04,
EXT2_FEATURE_OPTIONAL_EXTENDED_ATTRIBUTES = 0x08,
EXT2_FEATURE_OPTIONAL_CAN_RESIZE = 0x10,
EXT2_FEATURE_OPTIONAL_DIR_HASH_INDEX = 0x20,
};
#define EXT2_FEAT_OPT_SUPPORTED ( \
0 \
)
enum {
EXT2_FEATURE_REQUIRED_COMPRESSION = 0x01,
EXT2_FEATURE_REQUIRED_DIR_HAS_TYPE = 0x02,
EXT2_FEATURE_REQUIRED_JOURNAL_REPLAY_REQUIRED = 0x04,
EXT2_FEATURE_REQUIRED_HAS_JOURNAL_DEVICE = 0x08,
};
#define EXT2_FEAT_REQ_SUPPORTED ( \
EXT2_FEATURE_REQUIRED_DIR_HAS_TYPE | \
0 \
)
enum {
EXT2_FEATURE_RO_SPARSE_SUPERBLOCKS_AND_GROUPS_DESCRIPTOR = 0x01,
EXT2_FEATURE_RO_64BIT_SIZE = 0x02,
EXT2_FEATURE_RO_DIR_BTREE = 0X04
};
#define EXT2_FEAT_RO_64BIT_SIZE (SIZE_MAX > UINT32_MAX)
#define EXT2_FEAT_RO_SUPPORTED ( \
(EXT2_FEAT_RO_64BIT_SIZE ? EXT2_FEATURE_RO_64BIT_SIZE : 0) | \
0 \
)
typedef struct ext2_bg_descriptor {
uint32_t block_usage_bm;
uint32_t inode_usage_bm;
uint32_t start_block_inode;
uint16_t no_unallocated_blocks;
uint16_t no_unallocated_inodes;
uint16_t no_dirs;
uint8_t unused[14];
} ext2_bg_descriptor_t;
typedef struct ext2_inode {
union {
uint16_t type_permission;
struct {
uint8_t permission_o: 3;
uint8_t permission_g: 3;
uint8_t permission_u: 3;
bool permission_sticky: 1;
bool permission_setgid: 1;
bool permission_setuid: 1;
uint8_t type: 4;
} att_packed;
};
uint16_t uid;
uint32_t size_l;
uint32_t last_access;
uint32_t created;
uint32_t last_mod;
uint32_t deleted;
uint16_t gid;
uint16_t no_hard_links;
uint32_t no_sectors;
uint32_t flags;
uint32_t os_val1;
uint32_t dbp[12]; // fist 12 direct block pointers
uint32_t sibp;
uint32_t dibp;
uint32_t tibp;
uint32_t generation;
uint32_t extended_attr;
union {
uint32_t size_h;
uint32_t dir_acl;
};
uint32_t fragment_addr;
uint8_t os_val2[12];
} att_packed ext2_inode_t;
enum {
EXT2_INODE_FLAG_SECURE_DELETE = 0x00000001,
EXT2_INODE_FLAG_KEEP_COPY_ON_DELETE = 0x00000002,
EXT2_INODE_FLAG_FILE_COMPRESSION = 0x00000004,
EXT2_INODE_FLAG_SYNC_UPDATE = 0x00000008,
EXT2_INODE_FLAG_IMMUTABLE = 0x00000010,
EXT2_INODE_FLAG_APPEND_ONLY = 0x00000020,
EXT2_INODE_FLAG_NO_DUMP = 0x00000040,
EXT2_INODE_FLAG_LAST_ACCESS_IGNORE = 0x00000080,
EXT2_INODE_FLAG_HASH_INDEXED_DIR = 0x00010000,
EXT2_INODE_FLAG_AFS_DIRECTORY = 0x00020000,
EXT2_INODE_FLAG_JOURNAL_FILE_DATA = 0x00040000,
};
typedef struct ext2_dir_entry {
uint32_t inode;
uint16_t ent_size;
uint8_t name_size;
uint8_t type_or_name_size_h;
char name;
} ext2_dir_entry_t;
enum {
EXT2_INODE_TYPE_FIFO = 0x1,
EXT2_INODE_TYPE_CHAR_DEV = 0x2,
EXT2_INODE_TYPE_DIR = 0x4,
EXT2_INODE_TYPE_BLOCK_DEV = 0x6,
EXT2_INODE_TYPE_FILE = 0x8,
EXT2_INODE_TYPE_SYM_LINK = 0xA,
EXT2_INODE_TYPE_UNIX_SOCK = 0xC,
};
enum {
EXT2_DIR_TYPE_UNKNOWN = 0,
EXT2_DIR_TYPE_FILE = 1,
EXT2_DIR_TYPE_DIR = 2,
EXT2_DIR_TYPE_CHAR_DEV = 3,
EXT2_DIR_TYPE_BLOCK_DEV = 4,
EXT2_DIR_TYPE_FIFO = 5,
EXT2_DIR_TYPE_SOCKET = 6,
EXT2_DIR_TYPE_SOFT_LINK = 7,
};
typedef struct ext2_mount_info {
ext2_sb_t sb;
uint32_t no_block_groups;
uint64_t block_size;
uint64_t fragment_size;
void *block_dev;
} ext2_mount_info_t;
#endif //NEW_KERNEL_EXT2_H

View File

@@ -0,0 +1,36 @@
//
// Created by rick on 19-09-21.
//
#ifndef NEW_KERNEL_VFS_DRIVER_H
#define NEW_KERNEL_VFS_DRIVER_H
#include <myke/driver.h>
#include <myke/vfs/vfs.h>
typedef struct vfs_driver {
char name[16];
struct {
} flags;
// api
int (*vfs_mount)(vfs_mount_t *mount);
int (*open)(vfs_mount_t *mount, vfs_fd_t *dir, const char *path, int mode, vfs_fd_t *out);
int (*close)(vfs_mount_t *mount, vfs_fd_t *fd);
int (*fstat)(vfs_mount_t *mount, vfs_fd_t *fd, stat_t *target, int flags);
int (*fread)(vfs_mount_t *mount, vfs_fd_t *fd, void *target, size_t size);
int (*dgetent)(vfs_mount_t *mount, vfs_fd_t *fd, void *target, size_t size);
} __attribute__((__aligned__(STRUCT_ALIGNMENT))) vfs_driver_t;
void vfs_mk_dirent_record(vfs_dirent_t *ent, uint32_t inode, uint32_t cur_offset, uint8_t type, char *name,
size_t name_length);
#define VFS_DRIVER(order) GENERIC_DRIVER(vfs_driver, order)
#endif //NEW_KERNEL_VFS_DRIVER_H

70
include/myke/vfs/vfs.h Normal file
View File

@@ -0,0 +1,70 @@
//
// Created by rick on 19-09-21.
//
#ifndef NEW_KERNEL_VFS_H
#define NEW_KERNEL_VFS_H
#include <stdbool.h>
#include <sys/stat.h>
#define VFS_MOUNT_OK 0
#define VFS_MOUNT_ERROR 1
#define VFS_OPEN_ERROR 1
#define VFS_OPEN_OK 0
#define VFS_CLOSE_OK 1
#define VFS_READ_ERROR (-1)
#define VFS_DGETENTS_ERR 1
struct vfs_mount;
typedef struct vfs_mount {
struct {
} flags;
const char *prefix;
const char *device;
void *driver; // vfs_mount_driver_t
void *global_driver_data;
struct vfs_mount *next;
} vfs_mount_t;
typedef struct vfs_fd {
struct {
} flags;
vfs_mount_t *mount;
void *driver_data;
} vfs_fd_t;
#define VFS_DIRENT_BASE_SIZE (4 + 4 + 2 + 1)
#define VFS_DIRENT_SIZE(name_length) ((VFS_DIRENT_BASE_SIZE + (name_length) + 1 + 15) & (~0xF))
#define VFS_DIRENT_MAX_SIZE (VFS_DIRENT_BASE_SIZE + 256 + 1)
typedef struct vfs_dirent {
uint32_t inode;
uint32_t offset_next;
uint16_t reclen;
uint8_t type;
char name[];
} vfs_dirent_t;
int vfs_mount(const char *path, const char *device, const char *driver);
// https://man7.org/linux/man-pages/man2/open.2.html
vfs_fd_t *vfs_open(const char *path, int flags, int mode);
void vfs_close(vfs_fd_t *fd);
// https://man7.org/linux/man-pages/man2/stat.2.html
int vfs_fstat(vfs_fd_t *fd, stat_t *target, int flags);
// https://man7.org/linux/man-pages/man2/read.2.html
int vfs_read(vfs_fd_t *fd, void *target, size_t size);
// inspiration https://man7.org/linux/man-pages/man2/getdents.2.html
int vfs_getdents(vfs_fd_t *fd, void *target, int count);
#endif //NEW_KERNEL_VFS_H