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



back to months list

Project : The "Microkernel" Operating System

Journal Entry Date : 2025.10.22

Today I was planning on revising on my debug::out system, but while I was doing it, I realized that the segment manager system was somehow malfunctioning.

Upon investigating further, I realized that the reason behind it was the singleton model I'm using for global kernel structures... That moment I realized, I need something better than this singleton shenanigans.

The first thing I tried to solve this problem is to make a function that checks whether the given address is within the boundary of kstruct and pmem allocation. That way, the singleton object allocation will become much more "reliable", because it is guarenteed to know whether the singleton object has already been allocated or not. For ksturct, we can very easily implement this by comparing the address with the boundaries :

bool memory::is_kstruct_allocated_obj(void *obj) {
	return kstruct_mgr.boundary.start_address <= (max_t)obj && (max_t)obj <= kstruct_mgr.current_addr;
}

And for node-based memory allocators :

bool memory::is_pmem_allocated_obj(void *ptr) {
	SegmentsManager *segments_mgr = SegmentsManager::get_self();
	int index;
	if((index = segments_mgr->get_segment_index((max_t)ptr)) == -1) {
		return false;
	}
	return segments_mgr->node_managers[index].is_allocated((max_t)ptr);
}
...
// node manager

/// @brief Checks whether the provided address is the address to allocated object
/// @param address Address of memory chunk
bool memory::NodesManager::is_allocated(max_t address) {
	if(address < mem_start_address||address > mem_end_address) return false;
	struct Node *node = (struct Node *)(((max_t)address)-sizeof(struct Node));  // address of Node : address - Size of the node structure
	if((node->occupied == 0)||(node->signature != MEMMANAGER_SIGNATURE)) {			// If Node is not using, or not present, print error and leave.
		return false;
	}
	return true;
}

It's just identical to the first part of the free() mechanism.

The problem here, is that this didn't work.



* * *


No, I found the reason why.


You see that?

// At kernel/mem/segmentation.hpp : 
...
struct SegmentsManager : public DataManager {
    // ignore this, it's one of my attempts to solve this stupid error
    inline static SegmentsManager *__singleton_object_ptr;
    static SegmentsManager *get_self(void) {
        if(!memory::is_kstruct_allocated_obj(__singleton_object_ptr)) { 
            __singleton_object_ptr = (SegmentsManager *)memory::kstruct_alloc(sizeof(SegmentsManager));
        }
        return __singleton_object_ptr;
    }
...

// At kernel/mem/kmem_manager.hpp : 
// SegmentsManager : Manager of segments, decide what segments to be used next
// Global class, use singleton pattern
struct SegmentsManager {
    void init(int segment_count , struct Boundary *usable_segments);
    SINGLETON_PATTERN_KSTRUCT(struct SegmentsManager);
    
    int get_segment_index(max_t address);
    
    max_t get_currently_using_mem(void);
    max_t total_memory;
    int managers_count;
    NodesManager *node_managers;
};

There were two structures both having the same name!! What??

The amount of stupidity I feel about my past self. It's immeasurable.

Okay I don't think that was the real problem, but after tinkering and debugging with bunch of parts in the kernel, the problem just fixed itself. I'm kind of anxious whether I truly fixed the problem or not, but I think it's time to move on.