mov eax , cr0
or eax , 0x01
mov cr0 , eax



back to months list

Project : The "Microkernel" Operating System

Journal Entry Date : 2024.03.08

This entry is bit in a haze. The problem of ramdisk image being too big is solved. I just shrinked image size to 2MB and used FAT12 file system. (Surprisingly, fat12 file system works just identical to fat16..)

Implemented vfs::create() function. Whilst implementing, I just integrated iterated operation into just one function - functions such as searching the file_info handler and automatically creating new handle to the tree.

// @brief Get the file_info handle by using cache. 
///        If there is no file on the cache tree, function physically searches for the file.
///        The files opened for directory searching is stored into cache tree. 
/// @param file_path General file path
/// @param levels_to_exclude Number of directory levels to exclude from searching
/// @return file_info handle, if failed searching(file does not exist), return 0x00
static file_info *get_file_by_cache_and_phys(const general_file_name file_path , int levels_to_exclude) {
    vfs::VirtualFileSystemManager *vfs_mgr = GLOBAL_OBJECT(vfs::VirtualFileSystemManager);
    char **file_list;
    int level_count;
    int last_hit_loc = 0;

    // failed to initialize the vfs manager
    if(!vfs_mgr->is_initialized_properly) return 0x00;

    level_count = get_file_name_list(file_path , file_list);

    file_info *file = vfs_mgr->search_object_last(level_count , file_path.root_directory , file_list , last_hit_loc);
    if(file != 0x00 && strcmp(file->file_name , file_list[level_count-1]) == 0) { // cash hit
        memory::pmem_free(file_list);

        return file;
    }
    debug::out::printf_function(DEBUG_TEXT , "get_file_by_cache" , "last cash hit : %s(file=0x%lx), hit_loc : %d\n" , file->file_name , file , last_hit_loc);
    
    file_info *tree_file = file;
    for(int i = last_hit_loc; i < level_count-levels_to_exclude; i++) {
        physical_file_location *pfileloc = &tree_file->file_loc_info;
        if(tree_file->is_mounted == true) pfileloc = &tree_file->mount_loc_info;

        file_info *new_file_handle = pfileloc->fs_driver->get_file_handle({file_list[i] , tree_file});
        if(new_file_handle == 0x00) {
            memory::pmem_free(file_list);
            return 0x00;
        }

        vfs_mgr->add_object(new_file_handle , tree_file);
        tree_file = new_file_handle;
    }

    memory::pmem_free(file_list);
    return tree_file;
}

I just separated (very most of) operation searching cache from open() function and created a new function out of it.

Thanks to that, create() and open() functions are very very compact.

bool vfs::create(const general_file_name file_path , word file_type) {
    file_info *directory;
    physical_file_location *physical_loc;
    char top_name[strlen(file_path.file_name)];

    directory = get_file_by_cache_and_phys(file_path , 1);
    if(directory == 0x00) return false;
    physical_loc = fsdev::get_physical_loc_info(directory);
    get_highest_level_file_name(file_path.file_name , top_name);
    debug::out::printf("top_name : %s\n" , top_name);

    if(physical_loc->fs_driver == 0x00) return false;
    return physical_loc->fs_driver->create({top_name , directory} , file_type);
}

file_info *vfs::open(const general_file_name file_path , int option) {
    file_info *file = get_file_by_cache_and_phys(file_path , 0);
    return file;
}

get_highest_level_file_name() function is a function that parses the top name from the full file name. Basically it's the function that removes the directory path from the file. (Gosh, I should really name these functions more comprehensively...)

Now I'm planning on making open/close system and buffer caching system. I want file to be opened by multiple processors, each synchronized and cached. I really should learn how to do something fancy like linux..