src/kernel/mm/kheap.c
/**
 * \brief Function to allocate the heap for the kernel.
 * 
 * A heap is a vital component of both application programs and the kernel. 
 * It is also generally superseded by a higher level of memory management that deals with larger chunks of memory. 
 * For most operating systems memory will be allocated based on pages or other large chunks. 
 * 
 * This is used to dynamically allocate a single large block of memory with the specified size. 
 * It returns a pointer of type void which can be cast into a pointer of any form.
 * 
 * @param size Size (in bytes) to be allocated.
 * 
 * @return Allocated pointer
 */
\brief Function to allocate the heap for the kernel.

A heap is a vital component of both application programs and the kernel.
It is also generally superseded by a higher level of memory management that deals with larger chunks of memory.
For most operating systems memory will be allocated based on pages or other large chunks.

This is used to dynamically allocate a single large block of memory with the specified size.
It returns a pointer of type void which can be cast into a pointer of any form.

@param size Size (in bytes) to be allocated.

@return Allocated pointer
\ brief Function to allocate the heap for the kernel . A heap is a vital component of both application programs and the kernel . It is also generally superseded by a higher level of memory management that deals with larger chunks of memory . For most operating systems memory will be allocated based on pages or other large chunks . This is used to dynamically allocate a single large block of memory with the specified size . It returns a pointer of type void which can be cast into a pointer of any form . @param size Size ( in bytes ) to be allocated . @return Allocated pointer
void *kmalloc(uint32_t size) {
    int n = roundPageAligned(size + sizeof(kheapHeader)) / PAGE_SIZE;
    if (_kheapFirst == NULL) {
        _kheapFirst = vAllocPages(_kheapStart, BIT_PD_PT_PRESENT | BIT_PD_PT_RW, n, true);
        if(!_kheapFirst)
            return NULL;
        _kheapEnd += n * PAGE_SIZE;
        _kheapFirst->size = n * PAGE_SIZE;
        _kheapFirst->prev = NULL;
    }
    kheapHeader *block = _kheapFirst;
    while (block->next != NULL) {
        if (block->size == size) {
            block->prev->next = block->next;
            block->next->prev = block->prev;
            return block + sizeof(kheapHeader);
        } else if (block->size > size) {
            block->size -= (size + sizeof(kheapHeader));
            kheapHeader *ret_block = (uint32_t)block + block->size;
            ret_block->size = size;
            ret_block->prev = block;
            ret_block->next = block->next;
            return (void *)((uint32_t)ret_block + sizeof(kheapHeader));
        }
        block = block->next;
    } 
    if (block->size == size) {
        block->prev->next = block->next;
        block->next->prev = block->prev;
        return block + sizeof(kheapHeader);
    } else if (block->size > size) {
        block->size -= (size + sizeof(kheapHeader));
        kheapHeader *ret_block = (uint32_t)block + block->size;
        ret_block->size = size;
        ret_block->prev = block;
        ret_block->next = block->next;
        return (void *)((uint32_t)ret_block + sizeof(kheapHeader));
    }
    if ((uint32_t)_kheapEnd + n * PAGE_SIZE > (uint32_t)_kheapStart + KHEAP_LENGTH) {
        return NULL;
    }
    kheapHeader *new_block;
    new_block = vAllocPages(_kheapEnd, BIT_PD_PT_PRESENT | BIT_PD_PT_RW, n, true);
    if (!new_block)
        return NULL;
    _kheapEnd += (n * PAGE_SIZE); 
    new_block->size = n * PAGE_SIZE - size - sizeof(kheapHeader);
    new_block->prev = block;
    new_block->next = NULL;
    block->next = new_block;
    kheapHeader *ret_block = new_block + new_block->size;
    ret_block->size = size;
    ret_block->prev = new_block;
    ret_block->next = NULL;
    return ret_block + sizeof(kheapHeader);
}
void * kmalloc ( uint32_t size ) { int n = roundPageAligned ( size + sizeof ( kheapHeader ) ) / PAGE_SIZE ; if ( _kheapFirst == NULL ) { _kheapFirst = vAllocPages ( _kheapStart , BIT_PD_PT_PRESENT | BIT_PD_PT_RW , n , true ) ; if ( ! _kheapFirst ) return NULL ; _kheapEnd += n * PAGE_SIZE ; _kheapFirst -> size = n * PAGE_SIZE ; _kheapFirst -> prev = NULL ; } kheapHeader * block = _kheapFirst ; while ( block -> next != NULL ) { if ( block -> size == size ) { block -> prev -> next = block -> next ; block -> next -> prev = block -> prev ; return block + sizeof ( kheapHeader ) ; } else if ( block -> size > size ) { block -> size -= ( size + sizeof ( kheapHeader ) ) ; kheapHeader * ret_block = ( uint32_t ) block + block -> size ; ret_block -> size = size ; ret_block -> prev = block ; ret_block -> next = block -> next ; return ( void * ) ( ( uint32_t ) ret_block + sizeof ( kheapHeader ) ) ; } block = block -> next ; } if ( block -> size == size ) { block -> prev -> next = block -> next ; block -> next -> prev = block -> prev ; return block + sizeof ( kheapHeader ) ; } else if ( block -> size > size ) { block -> size -= ( size + sizeof ( kheapHeader ) ) ; kheapHeader * ret_block = ( uint32_t ) block + block -> size ; ret_block -> size = size ; ret_block -> prev = block ; ret_block -> next = block -> next ; return ( void * ) ( ( uint32_t ) ret_block + sizeof ( kheapHeader ) ) ; } if ( ( uint32_t ) _kheapEnd + n * PAGE_SIZE > ( uint32_t ) _kheapStart + KHEAP_LENGTH ) { return NULL ; } kheapHeader * new_block ; new_block = vAllocPages ( _kheapEnd , BIT_PD_PT_PRESENT | BIT_PD_PT_RW , n , true ) ; if ( ! new_block ) return NULL ; _kheapEnd += ( n * PAGE_SIZE ) ; new_block -> size = n * PAGE_SIZE - size - sizeof ( kheapHeader ) ; new_block -> prev = block ; new_block -> next = NULL ; block -> next = new_block ; kheapHeader * ret_block = new_block + new_block -> size ; ret_block -> size = size ; ret_block -> prev = new_block ; ret_block -> next = NULL ; return ret_block + sizeof ( kheapHeader ) ; }
\brief Function to allocate the heap for the kernel.
\ brief Function to allocate the heap for the kernel .
//If the first block isn't allocated, allocate it. // Eliminate this block from the list and return it // Modify the block subtracting the size // Set this up to have an easier freeing // Then return the calculated free address // Check on the last block (in this way, I won't lose it) // Eliminate this block from the list and return it // Modify the block subtracting the size // Set this up to have an easier freeing // Then return the calculated free address // Run out of memory // No memory, but available request some // Take the last part of the new chunk and return it