Added SimpleFS read support
This commit is contained in:
parent
758d681005
commit
4ec95a6a52
8 changed files with 174 additions and 107 deletions
|
@ -17,20 +17,138 @@
|
|||
/* SOFTWARE. */
|
||||
/*********************************************************************************/
|
||||
|
||||
#ifndef AXBOOT_UEFI
|
||||
#ifdef AXBOOT_UEFI
|
||||
|
||||
#include <vfs/drive.h>
|
||||
#include <vfs/vfs.h>
|
||||
#include <fs/uefi_sfs.h>
|
||||
#include <lib/string.h>
|
||||
#include <mm/mman.h>
|
||||
#include <print.h>
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
struct sfs_fsdata {
|
||||
EFI_FILE_PROTOCOL *volume;
|
||||
};
|
||||
|
||||
uint8_t sfs_read(char *filename, char *buffer, struct device *dev, void *fsdata)
|
||||
struct vfs_drive *sfs_init(char *mountpoint)
|
||||
{
|
||||
(void)dev;
|
||||
(void)fsdata;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL;
|
||||
EFI_GUID lip_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *iovolume;
|
||||
EFI_GUID sfs_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
||||
EFI_FILE_PROTOCOL *volume;
|
||||
EFI_STATUS status = EFI_SUCCESS;
|
||||
|
||||
status = gBootServices->HandleProtocol(gImageHandle, &lip_guid, (void **) &loaded_image);
|
||||
if (EFI_ERROR(status)) {
|
||||
debug("sfs_init(): Failed to open volume: %s (%lx)\n", efi_status_to_str(status), status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = gBootServices->HandleProtocol(loaded_image->DeviceHandle, &sfs_guid, (void *)&iovolume);
|
||||
if (EFI_ERROR(status)) {
|
||||
debug("sfs_init(): Failed to open volume: %s (%lx)\n", efi_status_to_str(status), status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = iovolume->OpenVolume(iovolume, &volume);
|
||||
if (EFI_ERROR(status)) {
|
||||
debug("sfs_init(): Failed to open volume: %s (%lx)\n", efi_status_to_str(status), status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
debug("sfs_init(): Opened boot volume\n");
|
||||
|
||||
struct vfs_filesystem *fs = (struct vfs_filesystem *)mem_alloc(sizeof(struct vfs_filesystem));
|
||||
if (fs == NULL) {
|
||||
debug("sfs_init(): Failed to allocate memory for filesystem structure!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sfs_fsdata *fsdata = (struct sfs_fsdata *)mem_alloc(sizeof(struct sfs_fsdata));
|
||||
if (fsdata == NULL) {
|
||||
debug("sfs_init(): Failed to allocate memory for private data!\n");
|
||||
mem_free(fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsdata->volume = volume;
|
||||
|
||||
fs->fsdata = fsdata;
|
||||
fs->read = sfs_read;
|
||||
fs->write = NULL; // sfs_write()
|
||||
|
||||
struct vfs_drive *drive = (struct vfs_drive *)mem_alloc(sizeof(struct vfs_drive));
|
||||
if (drive == NULL) {
|
||||
debug("sfs_init(): Failed to allocate memory for drive structure!\n");
|
||||
mem_free(fsdata);
|
||||
mem_free(fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drive->fs = fs;
|
||||
drive->read = NULL;
|
||||
drive->write = NULL;
|
||||
|
||||
return drive;
|
||||
}
|
||||
|
||||
size_t sfs_read(char *filename, char *buffer, struct vfs_drive *dev, void *fsdata)
|
||||
{
|
||||
struct sfs_fsdata *data = (struct sfs_fsdata *)fsdata;
|
||||
EFI_FILE_PROTOCOL *volume = data->volume;
|
||||
EFI_FILE_PROTOCOL *file;
|
||||
EFI_FILE_INFO *fileinfo;
|
||||
EFI_GUID fi_guid = EFI_FILE_INFO_GUID;
|
||||
EFI_UINTN fileinfo_size = sizeof(EFI_FILE_INFO) + 32;
|
||||
CHAR16 *wfilename;
|
||||
EFI_STATUS status = EFI_SUCCESS;
|
||||
size_t len = 0;
|
||||
|
||||
wfilename = (CHAR16 *)mem_alloc(strlen(filename) * sizeof(CHAR16));
|
||||
if (!wfilename) {
|
||||
debug("sfs_read(): Failed to allocate memory for wide strings!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbstowcs(wfilename, (const char **)&filename, strlen(filename));
|
||||
|
||||
/* open the file */
|
||||
status = volume->Open(volume, &file, wfilename, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
|
||||
if (EFI_ERROR(status)) {
|
||||
debug("sfs_read(): Failed to open file '%s': %s (%lx)\n", filename, efi_status_to_str(status), status);
|
||||
mem_free(wfilename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem_free(wfilename);
|
||||
|
||||
/* get file size */
|
||||
fileinfo = (EFI_FILE_INFO *)mem_alloc(fileinfo_size);
|
||||
if (!fileinfo) {
|
||||
debug("sfs_read(): Failed to allocate memory for file info!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
file->GetInfo(file, &fi_guid, &fileinfo_size, fileinfo);
|
||||
len = fileinfo->FileSize;
|
||||
|
||||
debug("sfs_read: %u\n", len);
|
||||
|
||||
buffer = (char *)mem_alloc(len * sizeof(char));
|
||||
if (!buffer) {
|
||||
debug("sfs_read(): Failed to allocate memory for output buffer!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
file->Read(file, &len, buffer);
|
||||
|
||||
/* close the file */
|
||||
file->Close(file);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,9 +18,22 @@
|
|||
/*********************************************************************************/
|
||||
|
||||
#include <vfs/vfs.h>
|
||||
#include <mm/mman.h>
|
||||
#include <print.h>
|
||||
|
||||
void axboot_init()
|
||||
{
|
||||
vfs_init();
|
||||
if (!vfs_init("/")) {
|
||||
debug("axboot_init(): Failed to mount boot drive! Halting...");
|
||||
// TODO: Halt
|
||||
while (1);
|
||||
}
|
||||
|
||||
// read kernel -> test read
|
||||
char *buffer = NULL;
|
||||
vfs_read("/System/axkrnl", buffer);
|
||||
|
||||
mem_free(buffer);
|
||||
|
||||
while (1);
|
||||
}
|
|
@ -32,7 +32,7 @@ size_t mbstowcs(wchar_t *dest, const char **src, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
while (count) {
|
||||
while (count--) {
|
||||
if ((*dest = *lsrc) == 0) {
|
||||
lsrc = NULL;
|
||||
break;
|
||||
|
@ -44,7 +44,6 @@ size_t mbstowcs(wchar_t *dest, const char **src, size_t len)
|
|||
|
||||
lsrc++;
|
||||
dest++;
|
||||
count--;
|
||||
}
|
||||
|
||||
return len - count;
|
||||
|
|
|
@ -30,74 +30,29 @@
|
|||
|
||||
#define MAX_MOUNTS 32
|
||||
|
||||
struct vfs_mount **mountpoints = NULL;
|
||||
uint8_t last_mount = 0;
|
||||
struct vfs_drive *boot_drive = NULL;
|
||||
|
||||
size_t str_backspace(char *str, char c)
|
||||
int vfs_init(char *root_mountpoint)
|
||||
{
|
||||
size_t i = strlen(str) - 1;
|
||||
boot_drive = mount_boot_volume(root_mountpoint);
|
||||
if (boot_drive == NULL) {
|
||||
debug("vfs_init(): Failed to allocate memory for VFS!\n");
|
||||
// fuck off and boot out early.
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (--i) {
|
||||
if (str[i] == c) {
|
||||
str[i+1] = 0;
|
||||
debug("vfs_init(): Mounted boot drive to \"/\"\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t vfs_read(char *filename, char *buf)
|
||||
{
|
||||
if (boot_drive->fs->read == NULL) {
|
||||
debug("vfs_read(): Filesystem didn't set up a read function!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns UINT8_MAX incase an error happens */
|
||||
uint8_t find_mntpoint_from_filename(char *filename, uint32_t *s_off)
|
||||
{
|
||||
char *orig = (char *)mem_alloc(strlen(filename) + 1);
|
||||
if (!orig) {
|
||||
debug("find_mntpoint_from_filename(): Failed to allocate memory for filename!\n");
|
||||
return UINT8_MAX;
|
||||
}
|
||||
|
||||
memset(orig, 0, strlen(filename) + 1);
|
||||
memcpy(orig, filename, strlen(filename) + 1);
|
||||
|
||||
if (orig[strlen(orig)] == '/')
|
||||
str_backspace(orig, '/');
|
||||
|
||||
// TODO: Check if there's a way to stay in this loop forever
|
||||
while (1) {
|
||||
for (int i = 0; i < MAX_MOUNTS; i++) {
|
||||
if (!mountpoints[i])
|
||||
break;
|
||||
|
||||
if (strcmp(mountpoints[i]->mnt, orig) == 0) {
|
||||
/* Adjust the orig to make it relative to the partition */
|
||||
*s_off = (strlen(orig) - 1);
|
||||
mem_free(orig);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(orig, "/") == 0)
|
||||
break;
|
||||
str_backspace(orig, '/');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vfs_init(void)
|
||||
{
|
||||
mountpoints = (struct vfs_mount **)mem_alloc(sizeof(struct vfs_mount) * MAX_MOUNTS);
|
||||
if (!mountpoints) {
|
||||
debug("vfs_init(): Failed to allocate memory for VFS!\n");
|
||||
// TODO: Panic and halt
|
||||
}
|
||||
}
|
||||
|
||||
int vfs_read(char *filename, char *buf, size_t len)
|
||||
{
|
||||
uint32_t s_off = 0;
|
||||
int i = find_mntpoint_from_filename(filename, &s_off);
|
||||
filename += s_off;
|
||||
|
||||
return mountpoints[i]->drive->fs->read(filename, buf, mountpoints[i]->drive, mountpoints[i]->drive->fs->fs_data);
|
||||
return boot_drive->fs->read(filename, buf, boot_drive, boot_drive->fs->fsdata);
|
||||
}
|
||||
|
||||
int vfs_write(char *filename, char *buf, size_t len)
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
#ifndef _FS_UEFI_SFS_H
|
||||
#define _FS_UEFI_SFS_H
|
||||
|
||||
#ifndef AXBOOT_UEFI
|
||||
#include <vfs/drive.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#endif
|
||||
struct vfs_drive *sfs_init(char *mountpoint);
|
||||
|
||||
size_t sfs_read(char *filename, char *buffer, struct vfs_drive *dev, void *fsdata);
|
||||
|
||||
#endif /* _FS_UEFI_SFS_H */
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*********************************************************************************/
|
||||
/* Module Name: bootmenu.h */
|
||||
/* Project: AurixOS */
|
||||
/* */
|
||||
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||
/* */
|
||||
/* This source is subject to the MIT License. */
|
||||
/* See License.txt in the root of this repository. */
|
||||
/* All other rights reserved. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||
/* SOFTWARE. */
|
||||
/*********************************************************************************/
|
||||
|
||||
#ifndef _MENU_BOOTMENU_H
|
||||
#define _MENU_BOOTMENU_H
|
||||
|
||||
void main_menu(void);
|
||||
|
||||
#endif /* _MENU_BOOTMENU_H */
|
|
@ -20,19 +20,15 @@
|
|||
#ifndef _VFS_VFS_H
|
||||
#define _VFS_VFS_H
|
||||
|
||||
#include <vfs/drive.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct vfs_drive;
|
||||
|
||||
struct vfs_filesystem {
|
||||
char *fsname;
|
||||
|
||||
uint8_t (*read)(char *, char *, struct vfs_drive *, void *);
|
||||
size_t (*read)(char *, char *, struct vfs_drive *, void *);
|
||||
uint8_t (*write)(char *, char *, size_t, struct vfs_drive *, void *);
|
||||
uint8_t (*mount)(struct vfs_drive *, void *);
|
||||
|
||||
uint8_t *fs_data;
|
||||
void *fsdata;
|
||||
};
|
||||
|
||||
struct vfs_mount {
|
||||
|
@ -40,9 +36,14 @@ struct vfs_mount {
|
|||
struct vfs_drive *drive;
|
||||
};
|
||||
|
||||
void vfs_init(void);
|
||||
int vfs_init(char *root_mountpoint);
|
||||
|
||||
int vfs_read(char *filename, char *buf, size_t len);
|
||||
/* This function allocates `buf`. Passing a non-NULL value will result in an error. */
|
||||
/* NOTE: Remember to free the allocated memory afterwards! */
|
||||
size_t vfs_read(char *filename, char *buf);
|
||||
int vfs_write(char *filename, char *buf, size_t len);
|
||||
|
||||
/* Every platform will define this on its own */
|
||||
struct vfs_drive *mount_boot_volume(char *mountpoint);
|
||||
|
||||
#endif /* _VFS_VFS_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*********************************************************************************/
|
||||
/* Module Name: main_menu.c */
|
||||
/* Module Name: mount.c */
|
||||
/* Project: AurixOS */
|
||||
/* */
|
||||
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||
|
@ -17,9 +17,12 @@
|
|||
/* SOFTWARE. */
|
||||
/*********************************************************************************/
|
||||
|
||||
#include <menu/bootmenu.h>
|
||||
#include <vfs/vfs.h>
|
||||
#include <fs/uefi_sfs.h>
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
void main_menu(void)
|
||||
struct vfs_drive *mount_boot_volume(char *mountpoint)
|
||||
{
|
||||
while (1);
|
||||
return sfs_init(mountpoint);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue