long kalloc(const register uint64_t length) { uint64_t* minAddress = (uint64_t*) lowest_available_physical_memory; // laveste addresse i memory uint64_t* maxAddress = (uint64_t*) top_of_available_physical_memory; // højeste adresse i memory uint64_t* allocationStart = (void*) minAddress; // return value to calling function starts on minAddress /*kprints("Start of kalloc\n"); kprints("Length is = "); kprinthex(length); kprints("\n"); */ struct Node* headOfChain = (struct Node*) minAddress; // the start node is set to the minimum address struct Node* basePoint; // alignedsize is the amount of memory to allocate (including the 32 byte alignment) uint64_t alignedSize = allign32(length); // calls method to align - now the block is diviable with 32 /*kprints("alignedSize = "); kprinthex(alignedSize); kprints("\n"); kprinthex((uint64_t)headOfChain->endOfNode);*/ // First time kalloc is runned if (firstRun == 'a') { kprints("FIRST TIME IN KALLOC!!!!\n\n"); basePoint = (struct Node*) minAddress; // new node created at start of memory basePoint->theNextNode = (struct Node*) maxAddress; // it is given a total size of maxaddress - minaddress basePoint->endOfNode = (uint64_t*) basePoint + headerSize + alignedSize; allocationStart = (uint64_t*) basePoint + headerSize; firstRun = 'b'; // NEVER TO COME BACK } else { // If the memory is not empty //kprints("Not first time i kalloc\n"); while (1) { // counter for the remaing free-space in the "array" uint64_t remainingSpaceOfMem = ((uint64_t*) headOfChain->theNextNode - (uint64_t*) headOfChain->endOfNode); if (remainingSpaceOfMem >= (uint64_t) alignedSize) { /// if the remaining memory is equal or larger than what's needed basePoint = (struct Node*) headOfChain->endOfNode; basePoint->theNextNode = headOfChain->theNextNode; headOfChain->theNextNode = basePoint; basePoint->endOfNode = (uint64_t*) basePoint + headerSize + alignedSize; // increment basePoint [___|______|_____] allocationStart = (uint64_t*) basePoint + headerSize; // break; } else { //kprints("WE CANNOT ALOCATE THAT MUCH SPACE\n"); // if max address reached we need to break, otherwise we increment the chain head. if (((uint64_t*) headOfChain->theNextNode) == maxAddress) { kprints("YOU HAVE REACHED MAX\n"); } else { //kprints("SETTING HEADOFCHAIN TO NEXT\n"); headOfChain = headOfChain->theNextNode; } } } } /* kprints("Return address = "); kprinthex((uint64_t) allocationStart); kprints("\n"); */ return (uint64_t) allocationStart; } extern long kfree(const register uint64_t address) { uint64_t* minAddress = (uint64_t*) lowest_available_physical_memory; uint64_t* maxAddress = (uint64_t*) top_of_available_physical_memory; //Check for outOfBound request. if ((uint64_t*) address < minAddress || (uint64_t*) address > maxAddress) { kprints("FREE ERROR (ADDRESS OUT OF RANGE)"); return ERROR; } // We have to trough the (possible) whole list, therefore we start at node 0. struct Node* headofChain = (struct Node*) minAddress; // This is what we are looking for struct Node* thisNode = (struct Node*) (uint64_t) address - headerSize; kprints("Trying to free node at address = "); kprinthex((uint64_t) thisNode); kprints("\n"); if (headofChain->theNextNode != 0) { // if the list is not empty. while ((uint64_t*) headofChain->theNextNode <= maxAddress) { //next node must start at smaller than max kprints("Next node to check is Node = "); kprinthex((uint64_t)headofChain); kprints("\n"); //if (headofChain <= thisNode && (uint64_t) thisNode<= (uint64_t) headofChain->endOfNode) { // thisnode == start of any other node//if (headofChain == thisNode) { if((headofChain->theNextNode) == thisNode){ headofChain->theNextNode = thisNode->theNextNode; // kprints("ALL GOOD\n"); return ALL_OK; } headofChain = (headofChain->theNextNode); } } else { kprints("ERROR: IN FREE WITH NO headOfChain->theNextNode\n"); } kprints("IN FREE ERROR2"); return ERROR; // -- should go trough list to check if thisNode is in the list, if not, it should return error else return ALL_OK } uint64_t allign32(uint64_t size) { uint64_t allignBlock = 0; // variable for allignment uint64_t allocationSize = 0; // variable for size allignBlock = size / 32; if (allignBlock * 32 < size) allignBlock++; allocationSize = allignBlock * 32; /*kprinthex(size); kprints("alignedSize = "); kprinthex(allocationSize); kprints("\n");*/ return allocationSize; }
struct Node { struct Node *theNextNode; uint64_t* endOfNode; };