Compare commits

...

23 Commits

Author SHA1 Message Date
notsomeidiot123 eecdfcb8bb Merge branch 'vfs-dev' 2026-07-11 15:08:39 -04:00
notsomeidiot123 739b0d8c71 Fixed memory corruption 2026-07-11 15:08:34 -04:00
notsomeidiot123 10bb61b738 Traced memory corruption problem 2026-07-06 22:04:06 -04:00
notsomeidiot123 616edd6bb3 Implemented ramfs functions, just missing close 2026-07-06 17:16:21 -04:00
notsomeidiot123 ecdeadc4f3 I realized i could cut out the middleman 2026-07-05 21:48:16 -04:00
notsomeidiot123 9065a5c68a Finished with ramfs_create(), rest of the VFS soon to follow 2026-07-05 21:36:23 -04:00
notsomeidiot123 817995394b Added spinlocks 2026-07-04 18:10:56 -04:00
notsomeidiot123 c5c9782535 Started on dynamically sizing ramfs files 2026-07-04 01:11:31 -04:00
notsomeidiot123 3b42ce5386 Return parent directory to new file in RAMFS 2026-07-04 00:33:10 -04:00
notsomeidiot123 02b5c8890a Added boolean format for printf 2026-07-04 00:10:13 -04:00
notsomeidiot123 f437724cb1 Fixed inconsistent behavior, removed unnecesary while loop 2026-06-27 15:00:46 -04:00
notsomeidiot123 047a057e9b Tokenizing path strings 2026-06-26 21:13:37 -04:00
notsomeidiot123 f20ee8046c solved some bugs, QEMU doesn't crash anymore 2026-06-26 20:19:55 -04:00
notsomeidiot123 daa915363d Qemu crashing; troubleshooting 2026-06-26 19:15:37 -04:00
notsomeidiot123 c2f258f1bb function defs for ramfs 2026-06-26 18:52:59 -04:00
notsomeidiot123 e5ce4d42d1 Commented out some code, may move or remove in the future 2026-06-26 13:52:57 -04:00
notsomeidiot123 9abca0e245 Decoupled ramfs from vfs functionality 2026-06-26 13:49:04 -04:00
notsomeidiot123 a83fc6a45d Small changes 2026-06-26 12:05:10 -04:00
notsomeidiot123 2062a2dff3 Defined file abstraction, separated ramfs into system/ramfs.c 2026-06-25 22:26:17 -04:00
notsomeidiot123 c79aeedae2 No clue what i'm doing 2026-06-25 20:46:29 -04:00
notsomeidiot123 335b386463 Adjustments to VFS API 2026-03-15 13:31:17 -04:00
notsomeidiot123 e366dc75d8 Modified files to fit new VFS 2026-03-14 13:48:00 -04:00
notsomeidiot123 cc61eec0cf Fixed unsafe/potentially buggy code 2026-03-14 11:29:44 -04:00
20 changed files with 618 additions and 470 deletions

View File

@ -1,4 +1,4 @@
CFLAGS="-g -c -m32 -fno-pie -mno-sse -O3 -D __bits__=32 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-incompatible-pointer-types -Wno-address-of-packed-member -Wno-discarded-qualifiers -fno-stack-protector -mno-red-zone -mno-sse -mno-sse2 -ffreestanding -nostdlib -mno-mmx"
CFLAGS="-g -c -m32 -fno-pie -mno-sse -O3 -D __bits__=32 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-incompatible-pointer-types -fno-stack-protector -mno-red-zone -mno-sse -mno-sse2 -ffreestanding -nostdlib -mno-mmx"
LDFLAGS_i386="-Ttext 0xc0000000 --oformat binary -melf_i386"
cd src/kernel/

View File

@ -21,13 +21,16 @@ bits 16
;Load part2 |x|
;Get video mode information |0|
;Set video mode |0|
;get memory map |0|
;enable paging |0|
;read filesystem |0|
;load kernel |0|
;parse ELF format |0|
;pass memory and video information to kernel|0|
;relocate and jump to kernel |0|
;get memory map |x|
;enable paging |x|
;read filesystem |x|
;load kernel |x|
;parse ELF format |x|
;pass memory and video information to kernel|x|
;relocate and jump to kernel |x|
;TODO 7/4/26
;Remember to ZERO THE BSS
jump:
jmp short start

View File

@ -4,6 +4,7 @@
#include "../system/vfs.h"
#include "../shared/string.h"
#include "../shared/memory.h"
#include "../drivers/serial.h"
#define MODULE_NAME "PCI"
char *classes[][20] = {
@ -45,16 +46,23 @@ void pci_read_file(vfile_t *file, uint32_t *buffer, uint32_t offset, uint32_t co
void pci_write_file(vfile_t *file, uint32_t *buffer, uint32_t offset, uint32_t count){
return;
}
fileops_t pci_fileops = {
0,
0,
pci_write_file,
pci_read_file,
};
void pci_make_file(uint32_t class, uint8_t bus, uint8_t slot, uint8_t func){
char *str = kmalloc(1);
memcpy("/dev/pci/", str, 9);
char str[256] = "/dev/pci/\0";
char *dev = classes[class >> 8][class & 0xf];
switch(class >> 8){
case 0x1://PCI class 0x1 is disks
// printf("!!STR: %s, LEN: %d!!", str, strlen(str));
strcpy("disk/", str + strlen(str));
uint32_t l = (uint32_t)pci_read_config(bus, slot, func, 0x4) | (uint32_t)pci_read_config(bus, slot, func, 0x6) << 16;
pci_write_config(bus, slot, func, 0x4, l | 4);
break;
case 0x2://PCI class 0x2 is network controllers
strcpy("net/", str + strlen(str));
@ -72,12 +80,21 @@ void pci_make_file(uint32_t class, uint8_t bus, uint8_t slot, uint8_t func){
char cpy[256];
vfile_t *file = 0;
uint8_t tries = 0;
while(file == 0){
// while(file == 0){
itoa(tries++, num, 10);
strcpy(str, cpy);
strcpy(num, cpy + strlen(cpy));
file = fcreate(cpy, VFILE_DEVICE, pci_write_file, pci_read_file);
}
file = fcreate(cpy, 0);
// file->read = pci_read_file;
// file->write = pci_write_file;
// if(file == 0) break;
if(!file){
mlog(MODULE_NAME, "Failed to make file for PCI device %s!\n", MLOG_PRINT, cpy);
return;
}
// printf("ASSERT file == null: %d\n", file == 0);
file->fileops = &pci_fileops;
// }
file->id = (uint32_t)slot | ((uint32_t)func << 8) | ((uint32_t)bus << 16);
}
@ -120,11 +137,11 @@ void pci_enumerate_bus(uint8_t bus){
void pci_init(){
mlog(MODULE_NAME, "Enumerating PCI Buses\n", MLOG_PRINT);
vfile_t *file = fcreate("dev/pci/", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("dev/pci/disk", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("dev/pci/net", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("dev/pci/video", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("dev/pci/bridge", VFILE_DIRECTORY, kmalloc(1), 1);
vfile_t *file = fcreate("/dev/pci/", FS_FILE_IS_DIR);
fcreate("/dev/pci/disk", FS_FILE_IS_DIR);
fcreate("/dev/pci/net", FS_FILE_IS_DIR);
fcreate("/dev/pci/video", FS_FILE_IS_DIR);
fcreate("/dev/pci/bridge", FS_FILE_IS_DIR);
for(uint32_t i = 0 ; i < 256; i++){
pci_enumerate_bus(i);
}

View File

@ -83,6 +83,10 @@ void vprintf(char *string, va_list vars){
num = va_arg(vars, int32_t);
printf((char[]){num, 0});
continue;
case 'b':
string++;
num = va_arg(vars, int32_t);
printf(num ? "true" : "false");
}
}
outb(com_ports[0], *string);

View File

@ -36,8 +36,18 @@ int read_initrd(initrd_t *initrd){
// }
char final_fname[80] = "/boot/";
strcat(file->filename, final_fname);
fcreate(final_fname, VFILE_POINTER, (archive + offset + sizeof(USTAR_file_t)), fsize_pgs);
vfile_t *tmp = fcreate(final_fname, 0);
if(!tmp){
mlog("INITRD", "Failed to read critical boot file: %s\n", MLOG_PRINT, file->filename);
return 1;
}
if(tmp->private){
kfree(tmp->private);
}
tmp->private = (archive + offset + sizeof(USTAR_file_t));
tmp->size = fsize_pgs * 4096;
// printf("%s, %d, %d\n", final_fname, filesize, fsize_pgs);
offset += (((filesize + 511) / 512) + 1) * 512;
}
return 0;
}

View File

@ -12,6 +12,7 @@
#include "system/vfs.h"
#include "drivers/ustar.h"
#include "system/initrc.h"
#include "system/ramfs.h"
kernel_info_t *boot_info = 0;
@ -23,21 +24,16 @@ void sysinit(){
pci_init();
// modules_init(boot_info, 0);
read_initrd(boot_info->initrd);
vfile_t *initrc = fget_file("/boot/initrc.conf");
if(initrc){
mlog("KERNEL", "Found initrc at: %x\n", MLOG_PRINT, initrc->access.data.ptr);
}
modules_init();
initrc_read(initrc);
// vfile_t *disk_dir = fget_file("/dev/disk");
// if(disk_dir == 0){
// mlog("KERNEL", "Error: /dev/disk does not exist\n", MLOG_PRINT);
// }
// vfile_t **dir_data = disk_dir->access.data.ptr;
// for(uint32_t i = 0; dir_data[i]; i++){
// mlog("KERNEL", "Filename: %s\n", MLOG_PRINT, dir_data[i]->name);
// vfs_detect_partitions(dir_data[i]);
// }
vfile_t *initrc = fopen("/boot/initrc.conf");
mlog("RAE", "\033[1;32mDid you remember to migrate your modules to the new API?\033[0m\n", MLOG_PRINT);
if(initrc){
mlog("KERNEL", "Found initrc\n", MLOG_PRINT);
initrc_read(initrc);
}
else{
mlog("KERNEL", "ERROR: Initrc could not be located!\n", MLOG_PRINT);
}
// dispatch_message(0);
printf("Bleh\n");
//why did i stop working on this? what was wrong with this?
@ -46,23 +42,24 @@ void sysinit(){
extern void kmain(kernel_info_t *kernel_info){
serial_init();
pm_init(kernel_info);
vfs_init();
ramfs_init();
mlog("KERNEL", "Initializing IDT\n", MLOG_PRINT);
idt_load();
pic_init(0x20);
pic_setmask(0x0, PIC1_DATA);
pic_setmask(0x0, PIC2_DATA);
fcreate("/dev", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("/dev/disk", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("/boot", VFILE_DIRECTORY, kmalloc(1), 1);
vfs_init();
fcreate("/tmp", FS_FILE_IS_DIR);
fcreate("/dev", FS_FILE_IS_DIR);
fcreate("/boot", FS_FILE_IS_DIR);
fcreate("/dev/disk", FS_FILE_IS_DIR);
mlog("KERNEL", "Initializing Scheduler & starting PID 1\n", MLOG_PRINT);
boot_info = kernel_info;
scheduler_init();
//scheduler doesn't work if there is no PID0, and I don't know why.
thread_start(pid0);
thread_start(sysinit);
// for(;;);
enable_interrupts();
for(;;);//we actually **shouldn't** return, like, ever. That's bad.
return;

View File

@ -4,6 +4,12 @@
#include "../drivers/serial.h"
#include "interrupts.h"
#define true 1
#define false 0
#define null 0
#define MLOG_DEBUG 1
#define MLOG_PRINT 2
#define MLOG_WARN 3
@ -27,6 +33,23 @@ void vector_set(uint32_t pos, vector_t *vector, void *new_element);
void vector_push(vector_t *vector, void *new_element);
void vector_pop(uint32_t pos, vector_t *vector, void *element);
uint32_t atoi(char *str, uint32_t base);
inline int32_t signed_max(int32_t i1, int32_t i2){
if(i1 > i2) return i1;
else return i2;
}
inline uint32_t unsigned_max(uint32_t i1, uint32_t i2){
if(i1 > i2) return i1;
else return i2;
}
inline int32_t signed_min(int32_t i1, int32_t i2){
if(i1 < i2) return i1;
else return i2;
}
inline uint32_t unsigned_min(uint32_t i1, uint32_t i2){
if(i1 < i2) return i1;
else return i2;
}

View File

@ -39,6 +39,8 @@
#define KMALLOC_LINK_NEXT 2
#define KMALLOC_LINK_LAST 4
#define PAGE_SIZE_BYTES 4096
typedef struct BIOS_data{
uint16_t com_ports[4];
uint16_t lpt_ports[3];

View File

@ -0,0 +1,13 @@
#include <stdatomic.h>
typedef struct spinlock{
atomic_flag lock;
}spinlock_t;
inline void spinlock_acquire(spinlock_t spinlock){
// atomic_compare_exchange_strong(&spinlock.lock, &spinlock.unlocked, spinlock.locked);
while(atomic_flag_test_and_set_explicit(&spinlock.lock, memory_order_acquire));
}
inline void spinlock_release(spinlock_t spinlock){
atomic_flag_clear_explicit(&spinlock.lock, memory_order_release);
}

View File

@ -21,6 +21,21 @@ inline uint32_t strcmp(char *str1, char *str2){
if(str1[i] == str2[i]) return 0;
else return 1;
}
inline void memclr(char *ptr, uint32_t count){
if(count % 4 == 0){
uint32_t *intptr = (uint32_t *)ptr;
for(uint32_t i = 0; i < count/4; i++){
intptr[i] = 0;
}
return;
}
for(uint32_t i = 0; i < count; i++){
ptr[i] = 0;
}
return;
}
char *strtok(char *str, char delim);
void strcpy(char *src, char *dest);
void memcpy(char *src, char *dest, uint32_t c);

View File

@ -1,5 +1,6 @@
#include "elf.h"
#include "../shared/kstdlib.h"
#include "../shared/string.h"
#include "../shared/memory.h"
#define MODULE_NAME "ELFLOAD"
@ -14,19 +15,9 @@ void *load_segment(program_entry_t entry, void *file_data, void *base_segment, u
// printf("Base: %x\n", base_segment);
if(entry.type == 1){
if(((elf_header_t *)(file_data))->type == ELF_TYPE_SHARED){
if(base_segment == 0){
segment = kmalloc(entry.msize/4096 + 1);
base_segment = segment;
}
else{
segment = base_segment + (entry.vaddr & 0xfffff000);
uint32_t count = 1;
count += ((entry.vaddr+entry.msize) - entry.vaddr) ? 1 : 0;
count += entry.msize/4096 + 1;
for(uint32_t i = 0; i < count; i++){
map(segment + (i << 12)/4, (void *)pm_alloc(), PT_PRESENT | map_flags);
}
}
segment = base_segment + (entry.vaddr & 0xfffff000);
memclr(segment, entry.msize);
for(uint32_t i = 0; i < entry.fsize/sizeof(uint32_t) + 1; i++){
segment[i] = ((uint32_t *)(file_data))[i + entry.data_offset/sizeof(uint32_t)];
}
@ -40,6 +31,7 @@ void *load_segment(program_entry_t entry, void *file_data, void *base_segment, u
//What is this for?
//TODO: Find out how to handle Dynamic sections
}
// printf("data_offset: %x\n", data_offset);
return base_segment;
}
@ -53,7 +45,12 @@ void *load_elf(void *file_data, uint32_t map_flags){
program_entry_t *program_header = file_data + header->program_header_offset;
uint32_t program_header_count = header->program_entry_count;
mlog(MODULE_NAME, "PROGRAM ENTRIES: %d\n", MLOG_PRINT, program_header_count);
void *base_segment = 0;
uint32_t size_pages = 0;
for(uint32_t i = 0; i < program_header_count; i++){
size_pages += (program_header[i].msize + PAGE_SIZE_BYTES - 1) / PAGE_SIZE_BYTES;
}
// printf("Requires %d pages\n", size_pages)
void *base_segment = kmalloc(size_pages);
for(uint32_t i = 0; i < program_header_count; i++){
base_segment = load_segment(program_header[i], file_data, base_segment, map_flags);
}

View File

@ -17,8 +17,12 @@ int is_num(char c){
void initrc_read(vfile_t *file){
mlog("KERNEL", "Reading initrc:\n", MLOG_PRINT);
char *ptr = file->access.data.ptr;
uint32_t size = file->access.data.size_pgs * 4096;
if(!file || !file->private){
mlog("KERNEL", "Failed to read initrc!\n", MLOG_PRINT);
return;
}
char *ptr = file->private;
uint32_t size = file->size;
char statement[512];
uint32_t i = 0;
while(strcmp(statement, "END")){
@ -52,18 +56,18 @@ void initrc_read(vfile_t *file){
i++;
char module_name[512];
int j = 0;
for(; j < 512 && ptr[i + j] && ptr[i+j] != '\n' && ptr[i + j] != ' '; j++){
for(; j < 512 && ptr[i + j] && ptr[i+j] != '\n' && ptr[i + j] != ' ' && i+j < size; j++){
module_name[j] = ptr[i + j];
}
i+=j;
module_name[j] = 0;
// printf("%s\n", module_name);
vfile_t *module = fget_file(module_name);
vfile_t *module = fopen(module_name);
if(!module){
printf("Error: Could not find module in Initrc.conf: %s\n", module_name);
continue;
}
module_start(module->access.data.ptr);
module_start(module->private);
}
else if(!strcmp(statement, "MOUNT")){
char mount_src_name[512] = {0};
@ -71,12 +75,12 @@ void initrc_read(vfile_t *file){
uint32_t offset = 0;
i++;
int j = 0;
for(; j < 512 && ptr[i + j] && ptr[i+j] != '\n' && ptr[i+j] != ' '; j++){
for(; j < 512 && ptr[i + j] && ptr[i+j] != '\n' && ptr[i+j] != ' ' && i+j < size; j++){
mount_src_name[j] = ptr[i + j];
}
i+=j;
mount_src_name[j] = 0;
for(j = 1; ptr[i + j] && ptr[i + j] != '\n' && ptr[i + j] != ' '; j++){
for(j = 1; ptr[i + j] && ptr[i + j] != '\n' && ptr[i + j] != ' ' && i+j < size; j++){
mount_dest[j-1] = ptr[i + j];
}
@ -115,10 +119,14 @@ void initrc_read(vfile_t *file){
// printf("TEST: %s, %s, %d\n", mount_src_name, mount_dest, ptr[i]);
vfile_t *to_mount = fget_file(mount_src_name);
vfile_t *to_mount = fopen(mount_src_name);
if(!to_mount){
mlog("KERNEL", "Could not locate file: %s. Aborting mount.\n", MLOG_PRINT, mount_src_name);
continue;
}
if(!dispatch_message(MESSAGE_MOUNT_FS, to_mount, mount_dest, offset)){
mlog("INITRC", "Error: Could not mount device %s at %s", MLOG_PRINT, mount_src_name, mount_dest);
asm("int $13");
// asm("int $13");
}
}
else if(!strcmp(statement, "END")){

View File

@ -69,26 +69,26 @@ uint32_t module_api(uint32_t func, ...){
uint32_t count = va_arg(vars, uint32_t);
return_value = fread(file, buffer, offset, count);
break;
case MODULE_API_WRITE:
case MODULE_API_WRITE:
file = va_arg(vars, vfile_t *);
buffer = va_arg(vars, char *);
offset = va_arg(vars, uint32_t), count = va_arg(vars, uint32_t);
count = va_arg(vars, uint32_t);
return_value = fwrite(file, buffer, offset, count);
break;
case MODULE_API_CREAT:
name = va_arg(vars, char *);
VFILE_TYPE ftype = va_arg(vars, VFILE_TYPE);
void *arg1, *arg2;
arg1 = va_arg(vars, void *);
arg2 = va_arg(vars, void *);
return_value = (uint32_t)fcreate(name, ftype, arg1, arg2);
FS_FILE_FLAGS ftype = va_arg(vars, FS_FILE_FLAGS);
return_value = (uint32_t)fcreate(name, ftype);
break;
case MODULE_API_DELET:
return_value = -1;
file = va_arg(vars, vfile_t *);
return_value = fdelete(file);
break;
case MODULE_API_OPEN:
name = va_arg(vars, char *);
return_value = (uint32_t)fget_file(name);
printf("Requested file: %s\n", name);
return_value = (uint32_t)fopen(name);
break;
case MODULE_API_MAP:
return_value = 0;

212
src/kernel/system/ramfs.c Normal file
View File

@ -0,0 +1,212 @@
#include "vfs.h"
#include "ramfs.h"
#include "../shared/kstdlib.h"
#include "../shared/memory.h"
#include "../shared/string.h"
#define MODULE_NAME "RAMFS"
fileops_t ramfs_ops =
{
ramfs_create,
ramfs_delete,
ramfs_write,
ramfs_read,
// ramfs_open,
ramfs_close,
ramfs_rfopen,
};
vfile_t root_dir = {"/", FS_FILE_IS_DIR | FS_FILE_SYSTEM, &ramfs_ops};
void ramfs_init(){
mlog(MODULE_NAME, "Initializing VFS\n", MLOG_PRINT);
root_dir.private = 0;
root_dir.size = 0;
}
vfile_t *search_dir(char *subname, vfile_t *directory){
if(!directory) return 0;
vfile_t **children = (vfile_t **)directory->private;
if(!children){
return 0;
}
for(int i = 0; i < directory->size / sizeof(vfile_t *); i++){
if(children[i] && !strcmp(children[i]->name, subname)){
return children[i];
}
}
return 0;
}
//resolves the path relative to start
vfile_t *resolve_path(char *pathname, vfile_t *start, uint32_t get_last_child){
const uint32_t MAX_TOKENS = PAGE_SIZE_BYTES/4;
if(!start){
return 0;
}
char *path = kmalloc(1);
strcpy(pathname, path);
char **path_tokens = kmalloc(1);
uint32_t pathname_entries = 0;
char *pathtok = path;
char *i = path;
while (*i != '\0') {
if (*i == '/') {
*i = '\0';
if (pathname_entries < MAX_TOKENS) {
path_tokens[pathname_entries++] = pathtok;
}
pathtok = i + 1;
}
i++;
}
if (pathname_entries < MAX_TOKENS) {
path_tokens[pathname_entries++] = pathtok;
}
// vfile_t **buffer = (vfile_t **)start->private;
vfile_t *entry = start;
char *current_path = pathname;
for(int i = 0; i < pathname_entries - !get_last_child; i++){
entry = search_dir(path_tokens[i], entry);
current_path += strlen(path_tokens[i]) + 1;
if(!entry){
break;
}
if(entry->flags & FS_FILE_MOUNT){
if(!get_last_child){
entry = 0;
break;
}
entry = entry->fileops->rfopen(current_path, entry);
break;
}
}
kfree(path);
kfree(path_tokens);
return entry;
}
char *get_filename(char *path){
char *filename = path + strlen(path) - 1;//get last character in pathname
while(*filename != path[0] && (*filename != '/' || filename == path)) filename--;
filename += filename != path;//if the new filename is at the beginning of the path, don't adjust for '/' character
return filename;
}
int ramfs_resize(vfile_t *file, uint32_t new_size_bytes){
if(new_size_bytes == file->size) return new_size_bytes;
uint32_t new_size_pages = (new_size_bytes + PAGE_SIZE_BYTES - 1)/PAGE_SIZE_BYTES;
uint32_t old_size_pages = (file->size + PAGE_SIZE_BYTES - 1)/PAGE_SIZE_BYTES;
do{
if(old_size_pages == new_size_pages){
break;
}
void *new_ptr = kmalloc(new_size_pages);
if(!new_ptr){
mlog(MODULE_NAME, "Failed to allocate memory for virtual file!\n", MLOG_PRINT);
return 0;
}
if(file->private){
memcpy((uint32_t *)file->private, (uint32_t*)new_ptr, file->size);
kfree(file->private);
}
file->private = new_ptr;
}while(0);
file->size = new_size_bytes;
return new_size_bytes;
}
vfile_t *ramfs_create(vfile_t *root, char *path, FS_FILE_FLAGS flags){
if(!path){
return 0;
}
if(path[0] == '/') path++;
// vfile_t *parent = resolve_path(path, root, false);
vfile_t *parent = root;
if(!parent || !parent->flags & FS_FILE_IS_DIR){
mlog(MODULE_NAME, "Could not locate parent directory for %s\n", MLOG_PRINT, path);
path--;
return 0;
}
char *new_name = path;
vfile_t **dirents = (vfile_t **)parent->private;
uint32_t insert_index = 0;
for(uint32_t i = 0; i < parent->size/sizeof(vfile_t *); i++){
if(dirents[i]){
continue;
}
//Empty dirent, can insert
vfile_t *new_file = kmalloc(1);
*new_file = (vfile_t){0};
// new_file->name = new_name;
strcpy(new_name, new_file->name);
new_file->flags = flags;
dirents[i] = new_file;
new_file->fileops = &ramfs_ops;
path--;
return new_file;
}
//no empty dirents, must resize
if( !ramfs_resize(parent, parent->size + 4)) return 0;
dirents = parent->private;
vfile_t *new_file = kmalloc(1);
if(!new_file) return 0;
*new_file = (vfile_t){0};
strcpy(new_name, new_file->name);
new_file->flags = flags;
dirents[parent->size/(sizeof(vfile_t*)) - 1] = new_file;
new_file->fileops = &ramfs_ops;
path--;
return new_file;
}
int ramfs_translate_dir(vfile_t *file, void *buffer, uint32_t offset, uint32_t count){
uint32_t dirents_requested = count / sizeof(vfile_t);
uint32_t dirents_availible = file->size / sizeof(vfile_t *);
uint32_t to_copy = unsigned_min(dirents_availible, dirents_requested);
vfile_t **dirents = (vfile_t **)file->private;
for(uint32_t i = 0; i < to_copy; i++){
memcpy(dirents[i], buffer + i * sizeof(vfile_t), sizeof(vfile_t));
}
return to_copy * sizeof(vfile_t);
}
int ramfs_delete(vfile_t *file){
return 0;
}
int ramfs_write(vfile_t *file, char *buffer, uint32_t offset, uint32_t count){
//file->private can be null here, as ramfs_resize will handle assigning if it is not already assigned
if(!file || !buffer || (file->flags & (FS_FILE_READ_ONLY | FS_FILE_IS_DIR | FS_FILE_MOUNT))) return 0;
if(!ramfs_resize(file, count + offset)) return 0;
memcpy(buffer, file->private + offset, count);
return count;
}
int ramfs_read(vfile_t *file, char *buffer, uint32_t offset, uint32_t count){
if(!file || !buffer || !file->private || file->flags & (FS_FILE_MOUNT)) return 0;
if(file->flags & FS_FILE_IS_DIR){
return ramfs_translate_dir(file, buffer, offset, count);
}
memcpy(file->private + offset, buffer, count);
return count;
}
// vfile_t *ramfs_open(char *path){
// return 0;
// }
void ramfs_close(vfile_t *file){
file->refcount--;
if(file->refcount < 0) file->refcount = 0;
return;
}
vfile_t *ramfs_rfopen(char *name, vfile_t *parent){
vfile_t *returnable = resolve_path(name, parent, true);
// for(;;);
return returnable;
}
vfile_t *get_root_dir(){
return &root_dir;
}

14
src/kernel/system/ramfs.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
void ramfs_init();
vfile_t *ramfs_create(vfile_t *parent, char *path, FS_FILE_FLAGS flags);
//Will never create a new reference
vfile_t *get_root_dir();
int ramfs_delete(vfile_t *file);
int ramfs_write(vfile_t *file, char *buffer, uint32_t offset, uint32_t count);
int ramfs_read(vfile_t *file, char *buffer, uint32_t offset, uint32_t count);
// vfile_t *ramfs_open(char *path);
void ramfs_close(vfile_t *file);
vfile_t *ramfs_rfopen(char *name, vfile_t *parent);

View File

@ -1,308 +1,120 @@
#include "vfs.h"
#include "ramfs.h"
#include "../shared/kstdlib.h"
#include "../shared/memory.h"
#include "../shared/string.h"
#define MODULE_NAME "KVFS"
vfile_t root_dir = {"/", VFILE_DIRECTORY};
// !TODO: Modify code to become thread-safe
// 3 months later: does this count?
struct mount_handler{
int (*callback)(vfile_t *device, MOUNT_OPERATION op, ...);
uint32_t key;
}mount_handlers[32];
int vfs_link_exists(vfile_t *file){
if(get_paddr(file) == 0 || file->type >= VFILE_MOUNT){
return 0;
}
return 1;
}
void vfs_write_part(vfile_t *file, void *data, uint32_t offset, uint32_t count){
if(!vfs_link_exists(file->parent) || count > file->size){
return;
}
fread(file->parent, data, offset + file->id, count);
}
void vfs_read_part(vfile_t *file, void *data, uint32_t offset, uint32_t count){
if(!vfs_link_exists(file->parent) || count > file->size){
return;
}
fwrite(file->parent, data, offset + file->id, count);
}
void vfs_detect_partitions(vfile_t *file){
char *buffer = kmalloc(1);
fread(file, buffer, 0, 512);
mbr_t *mbr = buffer;
if(mbr->magic != MBR_MAGIC){
mlog(MODULE_NAME, "No MBR!\n", MLOG_PRINT);
mlog(MODULE_NAME, "Magic: %x\n", mbr->magic, MLOG_PRINT);
return;
}
char cat[2] = {'a', 0};
char nfname[512] = {0};
strcpy(file->name, nfname);
strcat(cat, nfname);
char finalfname[512] = {0};
strcpy("/dev/", finalfname);
strcat(nfname, finalfname);
for(int i = 0; i < 4; i++){
partition_t part = mbr->partitions[i];
if(part.type == 0xee){
mlog(MODULE_NAME, "Found gpt\n", MLOG_PRINT);
return;
}
if((part.attributes != 0 && part.attributes != 0x80) ){
//check disk for filesystem
mlog(MODULE_NAME, "No partitions in %s\n", MLOG_PRINT, file->name);
// fcreate() new file representing partition
vfile_t *nfile = fcreate(finalfname, VFILE_DEVICE, vfs_write_part, vfs_read_part);
nfile->id = 0;
nfile->size = file->size;
nfile->parent = file;
return;
}
finalfname[strlen(finalfname)-1]++;
}
mlog(MODULE_NAME, "Magic: %x\n", MLOG_PRINT, mbr->magic);
return;
}
// void vfs_add_mount_handler(int (*mount_handler)(vfile_t *device, MOUNT_OPERATION op, ...), uint32_t key){
// if(mount_handler == 0){
// return;
// }
// for(uint32_t i = 0; i < 32; i++){
// if(mount_handlers[i].callback == 0){
// mount_handlers[i].callback = mount_handler;
// mount_handlers[i].key = key;
// }
// }
// }
// void vfs_del_mount_handler(uint32_t key){
// for(uint32_t i = 0; i < 32; i++){
// if(mount_handlers[i].key == key){
// mount_handlers[i].callback = 0;
// mount_handlers[i].key = 0;
// }
// }
// void add_file(vfile_t *vfile, vfile_t *current_dir){
// return;
// }
spinlock_t vfs_lock;
void vfs_init(){
mlog(MODULE_NAME, "Initializing VFS\n", MLOG_PRINT);
root_dir.access.data.ptr = kmalloc(1);
root_dir.access.data.size_pgs = 1;
spinlock_release(vfs_lock);
}
void add_file(vfile_t *vfile, vfile_t *current_dir){
vfile_t **dir_data = current_dir->access.data.ptr;
int i = 0;
while(dir_data[i] && (i * sizeof(vfile_t *))/4096 < current_dir->access.data.size_pgs){
i++;
}
dir_data[i] = vfile;
dir_data[i + 1] = 0;
vfile_t *fcreate(char *path, FS_FILE_FLAGS flags){
// return 0;
spinlock_acquire(vfs_lock);
vfile_t *returnable = vfcreate(get_root_dir(), path, flags);
spinlock_release(vfs_lock);
return returnable;
}
/*
Long comment cause this one's a complicated one.
Create a file of the specified path in name
if the path leads to a mounted filesystem then
use the mounted filesystem's specified create() function to create the file.
else, create a pointer in the virtual path that points to a file entry for the new file.
If this new file is a Directory or Pointer, specify a pointer to be used as a buffer to store data for this file, as well as the size of the buffer, in pages.
If this new file is a Mounted filesystem, this pointer must be an array of functions as defined below:
int fwrite(vfile_t *file, void *data, uint32_t offset, uint32_t count);
//must write count bytes from data to file offset by offset bytes.
int fread(vfile_t *file, void *data, uint32_t offset, uint32_t count);
//must read count bytes from data to file offset by offset bytes.
int fopen(char *filename, vfile_t *file);
//must return a vfile_t struct written to the address specified in file, to represent a file named name (from the mount's filename)
(eg. /mount/root/test is passed as /root/test)
fcreate(char *filename, FS_FILE_FLAGS flags);
FS_FILE_FLAGS is in the same format as FAT's file attribute byte of dirents.
filenames are truncated, as with the previous example.
fdelete(vfile_t *file);
//the file specified in the file pointer must be deleted.
else, if the file is a virtual representation of a device, of of a file (any miscellaneous file object that does not fit the other types) then
specify a pointer to be used as the read function, as defined below:
void read(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
specify a pointer to be used as the write function, with the same function prototype as the function above
void write(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
*/
vfile_t *fcreate(char *name, VFILE_TYPE type, ...){
name += name[0]== '/';
char *last = strtok(name, '/');
char *tmp = last;
uint32_t filename_offset = 0;
vfile_t *current_dir = &root_dir;
vfile_t *tmpfile;
vfile_t *vfcreate(vfile_t *parent_dir, char *relpath, FS_FILE_FLAGS flags){
if(!relpath){
return 0;
}
va_list args;
va_start(args, type);
while(tmp != 0){
// dir = tmp;
tmpfile = search_dir(tmp, *current_dir);
// printf("%s\n", name + filename_offset);
if(!tmpfile){
//create file in folder;
vfile_t *vfile = kmalloc(1);
vfile->type = type;
vfile->parent = current_dir;
uint32_t tmpnsize = strlen(tmp);
if(tmp[tmpnsize - 1] == '/'){
tmp[tmpnsize - 1] = 0;
}
strcpy(tmp, vfile->name);
switch(type){
case VFILE_POINTER:
case VFILE_DIRECTORY:
case VFILE_MOUNT:
case VFILE_SYMLINK:
case VFILE_FILE:
void *ptr = va_arg(args, void*);
vfile->access.data.ptr = ptr;
vfile->access.data.size_pgs = va_arg(args, uint32_t);
// *(uint32_t *)(ptr + (vfile->access.data.size_pgs * 4096)) = 0;
// what was the above line even for
add_file(vfile, current_dir);
break;
case VFILE_DEVICE:
void *write = va_arg(args, void *);
void *read = va_arg(args, void *);
vfile->access.funcs.write = write;
vfile->access.funcs.read = read;
// strcpy
add_file(vfile, current_dir);
break;
}
return vfile; //allow drivers to make last minute changes before it's sent to the user
}
if(tmpfile->type == VFILE_SYMLINK){
tmpfile = (vfile_t *)tmpfile->access.data.ptr;
}
switch(tmpfile->type){
case VFILE_DIRECTORY:
current_dir = tmpfile;
break;
case VFILE_MOUNT:
((mount_t*)(tmpfile->access.data.ptr))->create(name + filename_offset, type == VFILE_DIRECTORY ? FS_FILE_IS_DIR : 0);
return (void *)-1;
default:
// mlog(MODULE_NAME, "Error: Cannot create file with same name as another file! %d\n", MLOG_ERR, tmpfile->type);
return 0;
break;
}
filename_offset += strlen(tmp) + 1;
tmp = strtok(0, '/');
char *name = kmalloc((strlen(relpath) + 4095)/4096);//don't make modifications to the original string
strcpy(relpath, name);
if(name[0] == '/') name++;//first slash just indicates that it's an absolute path, we don't want to include that into the filename.
uint32_t name_length = strlen(name);
if(name[name_length-1] == '/') name[name_length - 1] = 0;
uint32_t name_index = 0;
uint32_t subpath_start = 0;
vfile_t *new_file = 0;
subpath_start = name_index;
while(name[name_index] && name[name_index] != '/'){//split the string at directories
name_index++;
}
return 0;
name[name_index] = 0;
if(name_index >= name_length){//if there is no other directory
new_file = parent_dir->fileops->create(parent_dir, name, flags);
}
else{
vfile_t *new_parent = rfopen(name, parent_dir);
if(!new_parent){
printf("No new parent found from name: %s!\n", name);
kfree(name);
return 0;
}
new_file = vfcreate(new_parent, name+name_index+1, flags);
// fclose(new_parent);
}
kfree(name);
return new_file;
// return 0;
}
//who needs a way to delete things?
//TODO: Write a function to delete files
void fdelete();
// navya was here https://github.com/novabansal
int fwrite(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count){
//sorry navya, I deleted the comment and it's not coming back :(
switch(file_entry->type){
case VFILE_DIRECTORY:
case VFILE_POINTER:
memcpy(byte_array, file_entry->access.data.ptr + offset, count);
return 0; //always successful. If it's not, there's been a page fault. Yk, quantum sort style.
break;
case VFILE_MOUNT:
case VFILE_FILE:
mount_t *funcs = file_entry->access.data.ptr;
return funcs->write(file_entry, byte_array, offset, count);
case VFILE_PDIR:
case VFILE_DEVICE:
return file_entry->access.funcs.write(file_entry, byte_array, offset, count);
break;
case VFILE_SYMLINK:
return fwrite(file_entry->access.data.ptr, byte_array, offset, count);
int fdelete(vfile_t *file_entry){
spinlock_acquire(vfs_lock);
if(!file_entry || !file_entry->fileops || !file_entry->fileops->delete){
return 0;
}
return INT32_MIN;//how did we get here?
spinlock_release(vfs_lock);
return file_entry->fileops->delete(file_entry);
}
//Is expected to overwrite, not append if it is an actual file
//Devices and anything Not A File is exempt (i.e. Blockdevs, chardevs, etc)
int fwrite(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count){
if(!file_entry || !file_entry->fileops || !file_entry->fileops->write ||!byte_array || count == 0){
return 0;
}
return file_entry->fileops->write(file_entry, byte_array, offset, count);
}
int fread(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count){
switch(file_entry->type){
case VFILE_DIRECTORY:
case VFILE_POINTER:
memcpy(file_entry->access.data.ptr + offset, byte_array, count);
return 0; //always successful. If it's not, there's been a page fault. Yk, quantum sort style.
break;
case VFILE_MOUNT:
case VFILE_FILE:
mount_t *funcs = file_entry->access.data.ptr;
return funcs->read(file_entry, byte_array, offset, count);
case VFILE_PDIR:
case VFILE_DEVICE:
return file_entry->access.funcs.read(file_entry, byte_array, offset, count);
break;
case VFILE_SYMLINK:
return fread(file_entry->access.data.ptr, byte_array, offset, count);
if(!file_entry || !file_entry->fileops || !file_entry->fileops->read || !byte_array || count == 0){
return 0;
}
return INT32_MIN; //Okay, alright, funny joke guys but we really shouldn't be able to get here
return file_entry->fileops->read(file_entry, byte_array, offset, count);
}
vfile_t *search_dir(char *name, vfile_t dir){
vfile_t **dir_data = (vfile_t **)dir.access.data.ptr;
uint32_t i = 0;
while(dir_data[i]){
if(!strcmp(dir_data[i]->name, name)){
return dir_data[i];
}
i++;
//fopen but relative to *dir
vfile_t *rfopen(char *name, vfile_t *dir){
if(!dir || !name || !dir->fileops || !dir->fileops->rfopen){
return 0;
}
return dir->fileops->rfopen(name, dir);
}
int readdir(vfile_t* file, vfile_t* buffer, uint32_t offset, uint32_t count){
return 0;
}
vfile_t *fget_file(char *name){
if(name[0] == '/'){
if(strlen(name) == 1){
return &root_dir;
}
name++;
vfile_t *fopen(char *name){
if(!name){
return 0;
}
if(name[strlen(name) - 1] == '/'){
name[strlen(name) - 1] = 0;
vfile_t *root = get_root_dir();
if(!strcmp(name, "/")){
return root;
}
// printf("%s\n", name);
char *dir = strtok(name, '/');
// printf("%s", name);
char *tmp = dir;
uint32_t filename_offset = 0;
vfile_t *current_dir = &root_dir;
vfile_t *tmpfile = 0;
while(tmp != 0){
dir = tmp;
tmpfile = search_dir(tmp, *current_dir);
if(!tmpfile){
// printf("not found\n");
return 0;
}
if(tmpfile->type == VFILE_SYMLINK){
tmpfile = (vfile_t *)tmpfile->access.data.ptr;
}
switch(tmpfile->type){
case VFILE_DIRECTORY:
// printf("found directory in %s: %s\n", current_dir->name, tmpfile->name);
current_dir = tmpfile;
break;
case VFILE_MOUNT:
vfile_t *file = kmalloc(1);
((mount_t*)(tmpfile->access.data.ptr))->open(name + filename_offset, file);
return file;
default:
return tmpfile;
}
filename_offset += strlen(tmp) + 1;
tmp = strtok(0, '/');
}
return tmpfile;
return root->fileops->rfopen(name + (name[0] == '/'), root);
}
vfile_t *fclose(vfile_t *file){
if(!file || !file->fileops || !file->fileops->close);
file->fileops->close(file);
return 0;
}

View File

@ -1,87 +1,59 @@
#pragma once
#include <stdint.h>
typedef enum vfile_type{
VFILE_NULL,
VFILE_POINTER,//virtual files
VFILE_DEVICE,
VFILE_MOUNT,//in the pointer passed to the function, must specify a read, write, open, create, and delete function.
VFILE_DIRECTORY,
VFILE_PDIR,//used for directories in physical filesystems.
VFILE_FILE,//physical files
VFILE_SYMLINK,
VFILE_PIPE //yay we have pipes
}VFILE_TYPE;
typedef enum mount_ops{
MOUNT_NEW,
MOUNT_UNMOUNT,
}MOUNT_OPERATION;
//this code is gonna be ***really*** unsafe
typedef struct virtual_file{
char name[20];
VFILE_TYPE type;
uint32_t id;//to be assigned by driver;
uint32_t mount_id;
uint8_t lock;
uint32_t size;
struct virtual_file *parent;//should point to A: a virtual directory, or B: a mounted filesystem
union{
struct{
int (*read)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
int (*write)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
}funcs;
struct{
void *ptr;
uint32_t size_pgs;
}__attribute__((packed))data;
}access;
}vfile_t;
#include "../shared/spinlock.h"
typedef enum fs_flags{
FS_FILE_READ_ONLY = 1,
FS_FILE_HIDDEN = 2,
FS_FILE_SYSTEM = 4,
FS_FILE_IS_DIR = 0x10,
FS_FILE_ARCHIVE = 0x20
FS_FILE_ARCHIVE = 0x20,
FS_FILE_PIPE = 0x40,
FS_FILE_LINK = 0x80,
FS_FILE_MOUNT = 0x100, // MUST be assigned to any file that represents a physical filesystem or physical device.
}FS_FILE_FLAGS;
typedef struct mount_funcs{
int (*write)(vfile_t *file, void *data, uint32_t offset, uint32_t count);
int (*read)(vfile_t *file, void *data, uint32_t offset, uint32_t count);
int (*open)(char *filename, vfile_t *file);
void (*delete)(vfile_t *file);
void (*create)(char *filename, FS_FILE_FLAGS flags);
}mount_t;
typedef struct fileops{
struct virtual_file *(*create)(struct virtual_file *parent, char *path, FS_FILE_FLAGS flags);
int (*delete)(struct virtual_file *file_entry);
int (*write)(struct virtual_file *file_entry, void *data, uint32_t offset, uint32_t count);
int (*read)(struct virtual_file *file_entry, void *data, uint32_t offset, uint32_t count);
// struct virtual_file *(*open)(char *path);
void (*close)(struct virtual_file *file);
// int (*readdir)(struct virtual_file* file, struct virtual_file *buffer, uint32_t count, uint32_t offset);
struct virtual_file *(*rfopen)(char *name, struct virtual_file *parent);
} fileops_t;
typedef struct partition{
uint8_t attributes;
uint8_t chs_start[3];
uint8_t type;
uint8_t chs_end[3];
uint32_t lba_start;
uint32_t lba_size;
}__attribute__((packed))partition_t;
#define MBR_MAGIC 0xaa55
typedef struct mbr{
char code[440];
char id[4];
char res[2];
partition_t partitions[4];
uint16_t magic;
}__attribute__((packed)) mbr_t;
//note: this is EXACTLY 256 bytes. This is for simplicity's sake.
//PLEASE if you MUST reorganize or add fields, try and keep it to a power of 2?
typedef struct virtual_file{
char name[212];
uint16_t flags;
fileops_t *fileops;
uint32_t refcount; //filesystem MUST remain operational until all child refcounts == 0
uint32_t id;//for use in drivers
void *private; //also for use in drivers
uint32_t size; //should be in bytes
uint32_t offset; //for use in drivers
uint8_t owner_uid;
uint8_t owner_gid;
uint32_t last_modified;
uint32_t created;
uint16_t permissions; //same format as linux
spinlock_t lock;
}vfile_t;
void vfs_init();
vfile_t *fcreate(char *name, VFILE_TYPE type, ...);
void fdelete();
// vfile_t *rfopen(char *name, vfile_t dir);
vfile_t *fcreate(char *path, FS_FILE_FLAGS flags);
int fdelete(vfile_t* file_entry);
int fwrite(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count);
int fread(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count);
vfile_t *search_dir(char *name, vfile_t dir);
vfile_t *fget_file(char *name);
// void vfs_del_mount_handler(uint32_t key);
// void vfs_add_mount_handler(int (*mount_handler)(vfile_t *device, MOUNT_OPERATION op, ...), uint32_t key);
void vfs_detect_partitions(vfile_t *file);
// int readdir(vfile_t* file, vfile_t *buffer, uint32_t offset, uint32_t count);
vfile_t *vfcreate(vfile_t *parent, char *relpath, FS_FILE_FLAGS flags);
vfile_t *rfopen(char *name, vfile_t *dir);
vfile_t *fclose(vfile_t *);
vfile_t *fopen(char *path);

View File

@ -8,6 +8,17 @@
KOS_MAPI_FP api;
int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count);
int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count);
fileops_t ide_fileops = {
0,
0,
ata_write,
ata_read,
0,
0,
};
/*
TODO:
Register module
@ -208,7 +219,7 @@ int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
if (count == 0) return -1;
ata_acquire_primary_lock();
// }
drive_t drive = drives[file->mount_id];
drive_t drive = drives[file->id];
uint16_t io_base = drive.BARs[0] &0xfffe;
uint16_t ctrl_base = drive.BARs[1] &0xfffe;
uint16_t bm_base = drive.BARs[4] & ~3;
@ -283,7 +294,7 @@ int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
asm("sti");
transferring_disk_index = file->mount_id;
transferring_disk_index = file->id;
uint8_t status = inb(ctrl_base);
uint8_t bm_status = inb(bm_base + 2);
@ -303,7 +314,7 @@ int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count) {
if (count == 0) return -1;
drive_t drive = drives[file->mount_id];
drive_t drive = drives[file->id];
uint16_t io_base = drive.BARs[0] &0xfffe;
uint16_t ctrl_base = drive.BARs[1] &0xfffe;
uint16_t bm_base = drive.BARs[4] & ~3;
@ -372,14 +383,15 @@ int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count) {
recieved_ints = 0;
asm("cli");
transferring_disk_index = file->mount_id;
transferring_disk_index = file->id;
uint32_t cpid = api(MODULE_API_GET_CPID);
// api(MODULE_API_PRINT, MODULE_NAME, "Cpid: %x", cpid);
api(MODULE_API_BLOCK_PID, cpid);
transferring_pid = cpid;
outb(bm_base, 0x09);
asm("sti");
// asm("sti"); // TODO: Make it so that instead of sti(), restore interrupt flag
if(!api(MODULE_API_IS_INTERRUPT)) asm("sti");
uint8_t status = inb(ctrl_base);
uint8_t bm_status = inb(bm_base + 2);
@ -522,8 +534,19 @@ uint8_t ata_identify(uint32_t index, uint16_t disk){
uint32_t prdt_phys = api(MODULE_API_PMALLOC64K);
drives[index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_phys, 16);
itoa(ata_drives, fname + strlen(fname), 10);
vfile_t *new_file = fcreate(api, fname, VFILE_DEVICE, ata_write, ata_read);
new_file->mount_id = index;
vfile_t *new_file = fcreate(api, fname, FS_FILE_SYSTEM);
api(MODULE_API_PRINT, MODULE_NAME, "New File: %x, Name: %s\n", new_file, new_file->name);
//
//
//
// RIGHT HERE
//
//
//
// new_file->read = ata_read;
// new_file->write = ata_write;
new_file->id = index;
new_file->fileops = &ide_fileops;
puts(api, "KIDM", "Valid Drive!\n");
return 0;
}
@ -596,10 +619,22 @@ void init(KOS_MAPI_FP module_api, uint32_t api_version){
api(MODULE_API_ADDINT, 15, module_data.key, int_handler);
api(MODULE_API_ADDINT, 14, module_data.key, int_handler);
// api(MODULE_API_ADDINT, 0, module_data.key, int_handler);
vfile_t *pci_drive_dir = fget_file(api, "/dev/pci/disk/");
vfile_t **dir_data = (pci_drive_dir->access.data.ptr);
for(uint32_t i = 0; dir_data[i]; i++){
vfile_t *current_file = dir_data[i];
vfile_t *pci_drive_dir = fopen(api, "/dev/pci/disk");
if(!pci_drive_dir){
puts(api, MODULE_NAME, "Failed to open /dev/pci/disk\n");
return;
}
// vfile_t **dir_data = (pci_drive_dir->ptr);
const uint32_t PCI_SEARCH_COUNT = 64;
vfile_t *dir_data = malloc(api, (PCI_SEARCH_COUNT * sizeof(vfile_t) + 4095)/4096);
uint32_t file_count = api(MODULE_API_READ, pci_drive_dir, dir_data, 0, PCI_SEARCH_COUNT * sizeof(vfile_t))/sizeof(vfile_t);
api(MODULE_API_PRINT, MODULE_NAME, "File count: %x\n", file_count);
for(uint32_t i = 0; i < file_count; i++){
vfile_t *current_file = &(dir_data[i]);
uint32_t class = 0;
fread(api, current_file, &class, 0x8, 1);
uint32_t progif = class >> 8 & 0xff;

View File

@ -23,16 +23,16 @@ uint8_t fat32_check_valid(fat32_bpb_t *bpb){
uint32_t fat32_mount(vfile_t *dev_file, char *destination, uint32_t offset){
char *bpb_buffer = malloc(api, 1);
fread(api, dev_file, bpb_buffer, offset, 4096);
fat32_bpb_t *bpb = bpb_buffer;
// char *bpb_buffer = malloc(api, 1);
// fread(api, dev_file, bpb_buffer, offset, 4096);
// fat32_bpb_t *bpb = bpb_buffer;
api(MODULE_API_PRINT, MODULE_NAME, "Sizeof struct: %d, sig: %x, boot sig: %x\n", sizeof(fat32_bpb_t), bpb->signature, bpb->bootable_sig);
if(!fat32_check_valid(bpb)){
api(MODULE_API_PRINT, MODULE_NAME, "Error: No valid BPB\n");
return 0;
}
puts(api, MODULE_NAME, "Valid BPB found!\n");
// api(MODULE_API_PRINT, MODULE_NAME, "Sizeof struct: %d, sig: %x, boot sig: %x\n", sizeof(fat32_bpb_t), bpb->signature, bpb->bootable_sig);
// if(!fat32_check_valid(bpb)){
// api(MODULE_API_PRINT, MODULE_NAME, "Error: No valid BPB\n");
// return 0;
// }
// puts(api, MODULE_NAME, "Valid BPB found!\n");
// fat32_make_mount();
@ -59,8 +59,8 @@ void init(KOS_MAPI_FP module_api, uint32_t api_version){
api(MODULE_API_PRINT, MODULE_NAME, "KIFSM Filesystem Driver Module v0.1.0\nSupported Filesystems:\n");
int32_t status = api(MODULE_API_REGISTER, &module_data);
api(MODULE_MESSAGE_HANDLER, module_data.key, message_handler);
api(MODULE_API_PRINT, MODULE_NAME, "Key: %x\n", module_data.key);
// api(MODULE_MESSAGE_HANDLER, module_data.key, message_handler);
// api(MODULE_API_PRINT, MODULE_NAME, "Key: %x\n", module_data.key);
return;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <stdint.h>
#include "../kernel/shared/spinlock.h"
enum MODULE_API_FUNCS{
@ -53,34 +54,47 @@ enum MESSAGES{
MESSAGE_BROADCAST = 0x80000000, //placeholder
};
typedef enum vfile_type{
VFILE_NULL,
VFILE_POINTER,
VFILE_DEVICE,
VFILE_MOUNT,
VFILE_DIRECTORY,
VFILE_PDIR,//used for directories in physical filesystems.
VFILE_FILE,
}VFILE_TYPE;
typedef enum fs_flags{
FS_FILE_READ_ONLY = 1,
FS_FILE_HIDDEN = 2,
FS_FILE_SYSTEM = 4,
FS_FILE_IS_DIR = 0x10,
FS_FILE_ARCHIVE = 0x20,
FS_FILE_PIPE = 0x40,
FS_FILE_LINK = 0x80,
FS_FILE_MOUNT = 0x100, // MUST be assigned to any file that represents a physical filesystem or physical device.
}FS_FILE_FLAGS;
typedef struct fileops{
struct virtual_file *(*create)(struct virtual_file *parent, char *path, FS_FILE_FLAGS flags);
int (*delete)(struct virtual_file *file_entry);
int (*write)(struct virtual_file *file_entry, void *data, uint32_t offset, uint32_t count);
int (*read)(struct virtual_file *file_entry, void *data, uint32_t offset, uint32_t count);
// struct virtual_file *(*open)(char *path);
void (*close)(struct virtual_file *file);
// int (*readdir)(struct virtual_file* file, struct virtual_file *buffer, uint32_t count, uint32_t offset);
struct virtual_file *(*rfopen)(char *name, struct virtual_file *parent);
} fileops_t;
//note: this is EXACTLY 256 bytes. This is for simplicity's sake.
//PLEASE if you MUST reorganize or add fields, try and keep it to a power of 2?
typedef struct virtual_file{
char name[20];
VFILE_TYPE type;
uint32_t id;//to be assigned by driver;
uint32_t mount_id;
uint8_t lock;
uint32_t size;
struct virtual_file *parent;//should point to A: a virtual directory, or B: a mounted filesystem
union{
struct{
int (*read)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
int (*write)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
}funcs;
struct{
void *ptr;
uint32_t size_pgs;
}__attribute__((packed))data;
}access;
char name[212];
uint16_t flags;
fileops_t *fileops;
uint32_t refcount; //filesystem MUST remain operational until all child refcounts == 0
uint32_t id;//for use in drivers
void *private; //also for use in drivers
uint32_t size; //should be in bytes
uint32_t offset; //for use in drivers
uint8_t owner_uid;
uint8_t owner_gid;
uint32_t last_modified;
uint32_t created;
uint16_t permissions; //same format as linux
spinlock_t lock;
}vfile_t;
inline void *malloc(KOS_MAPI_FP api, uint32_t size_pages){
@ -90,7 +104,7 @@ inline void *free(KOS_MAPI_FP api, void *ptr){
api(MODULE_API_FREE, ptr);
return 0;
}
inline vfile_t *fget_file(KOS_MAPI_FP api, char *filename){
inline vfile_t *fopen(KOS_MAPI_FP api, char *filename){
// vfile_t *file = malloc(api, 1);
return (void *)api(MODULE_API_OPEN, filename);
}
@ -101,8 +115,8 @@ inline int fwrite(KOS_MAPI_FP api, vfile_t *file, char *buffer, uint32_t offset,
return api(MODULE_API_WRITE, file, buffer, offset, count);
}
//read documenation for this one
inline vfile_t *fcreate(KOS_MAPI_FP api, char *filename, VFILE_TYPE type, char *pointer_write, char *size_read){
return (void *)api(MODULE_API_CREAT, filename, type, pointer_write, size_read);
inline vfile_t *fcreate(KOS_MAPI_FP api, char *filename, FS_FILE_FLAGS type){
return (void *)api(MODULE_API_CREAT, filename, type);
}
inline void puts(KOS_MAPI_FP api, char *mname, char *str){
api(MODULE_API_PRINT, mname, str);