Provided Files
This commit is contained in:
8
Part3/09_memory/libc/function.h
Normal file
8
Part3/09_memory/libc/function.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef FUNCTION_H
|
||||
#define FUNCTION_H
|
||||
|
||||
/* Sometimes we want to keep parameters to a function for later use
|
||||
* and this is a solution to avoid the 'unused parameter' compiler warning */
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#endif
|
11
Part3/09_memory/libc/globals.c
Normal file
11
Part3/09_memory/libc/globals.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "globals.h"
|
||||
|
||||
u32 kmem_addr;
|
||||
u32 kernel_mem_limit;
|
||||
|
||||
u32 umem_addr;
|
||||
u32 user_mem_limit;
|
||||
|
||||
u32 global_id;
|
||||
|
||||
node *global_head;
|
23
Part3/09_memory/libc/globals.h
Normal file
23
Part3/09_memory/libc/globals.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#include "../cpu/types.h"
|
||||
#include "linked.h"
|
||||
|
||||
// Using defines allows this file to control the ranges here rather than updating the kernel code lines
|
||||
// somewhere else at various locations throughout the code
|
||||
// using ALL CAPS is a conventions for defines and constants, that varies from group to group
|
||||
#define KMEM_START 0x9000 // starts equal to this address for allocation
|
||||
#define KMEM_END 0x10000 // cannot be equal to or more than this address
|
||||
extern u32 kmem_addr; // The start value of allocation kernel datastructure allocations
|
||||
extern u32 kernel_mem_limit; // the upper limit of memory allowed for kernel memory allocations
|
||||
|
||||
#define UMEM_START 0x10000 // kernel memory for linked list nodes starts here
|
||||
#define UMEM_END 0x40000 // kernel memory for linked list nodes must end before here
|
||||
extern u32 umem_addr; // start of linked list memory allocation address
|
||||
extern u32 user_mem_limit; // end of linked list memory allocation address
|
||||
|
||||
extern u32 global_id; // Just an id for now but will eventually become PID
|
||||
|
||||
extern node *global_head; // Kernel data structure for storing memory allocation linked list
|
||||
#endif // GLOBAL_H
|
480
Part3/09_memory/libc/linked.c
Normal file
480
Part3/09_memory/libc/linked.c
Normal file
@@ -0,0 +1,480 @@
|
||||
// linked.c ANSI C kernel environment linked list
|
||||
// requires kmalloc to allocate space for linked list
|
||||
|
||||
#include "linked.h"
|
||||
|
||||
// Create a blank node using kmalloc, then use allocated memory to store
|
||||
// a linked list node with the values passed in the parameters
|
||||
// You must capture the node returned with an lval result variable
|
||||
node *create_node( u32 base_register, u32 limit_register, bool ft_hole_mem, u32 id)
|
||||
{
|
||||
node *new_node = NULL;
|
||||
|
||||
new_node = (node *) kmalloc( NODE_SIZE, 0, (u32 *) new_node);
|
||||
new_node->id = id;
|
||||
new_node->base_register = base_register;
|
||||
new_node->limit_register = limit_register * (new_node->id + 1);
|
||||
new_node->ft_hole_mem = ft_hole_mem;
|
||||
new_node->next = NULL;
|
||||
new_node->previous = NULL;
|
||||
|
||||
return( new_node);
|
||||
}
|
||||
|
||||
// Creates a node from parameters using the above and then passes it to insert the node into the linked list
|
||||
// changes to *head will only affect a local stack variable
|
||||
// You must capture the new head returned with an lval result variable to update head changes
|
||||
// ft_hole_mem is not used currently but is included to maintain a "holes" list
|
||||
// true means update memory list, false means update holes list (if you were to use it)
|
||||
node *add_node( node *head, u32 base_register, u32 limit_register, bool ft_hole_mem, u32 id)
|
||||
{
|
||||
node *new_node = NULL;
|
||||
|
||||
new_node = create_node( base_register, limit_register, ft_hole_mem, id);
|
||||
head = _add_node( head, new_node);
|
||||
return( head);
|
||||
}
|
||||
|
||||
// place an already created node at the end of the list
|
||||
// changes to *head will only affect a local stack variable
|
||||
// You must capture the new head returned with an lval result variable to update head changes
|
||||
node *_add_node( node *head, node *new_node)
|
||||
{
|
||||
node *iterator = NULL;
|
||||
node *previous = NULL;
|
||||
|
||||
if( new_node == NULL) {
|
||||
return(head);
|
||||
}
|
||||
if( head == NULL) {
|
||||
head = new_node;
|
||||
return ( head );
|
||||
} // Stop here is head is empty and just set to new and return new head.
|
||||
|
||||
iterator = head->next; // Head is not NULL so continue with next node as iterator
|
||||
while( iterator != NULL) {
|
||||
previous = iterator;
|
||||
iterator = iterator->next;
|
||||
} // until iterator is null keep pointing new node back to previous node and iterator to next node
|
||||
|
||||
if( previous == NULL) { // just head existed, append new node ...
|
||||
new_node->previous = head;
|
||||
head->next = new_node;
|
||||
} else { // iterated to end of list, append new node ...
|
||||
new_node->previous = previous;
|
||||
previous->next = new_node;
|
||||
} // ... and return
|
||||
return( head);
|
||||
}
|
||||
|
||||
// Iterate to last node and list and then append new node to it
|
||||
node *append_node( node *head, node* new_node)
|
||||
{
|
||||
node *iterator = head;
|
||||
|
||||
if( new_node == NULL) {
|
||||
return( head);
|
||||
}
|
||||
if( head == NULL) {
|
||||
return( new_node);
|
||||
}
|
||||
while( iterator->next != NULL) { // step until at last node
|
||||
iterator = iterator->next;
|
||||
}
|
||||
iterator->next = new_node;
|
||||
new_node->previous = iterator;
|
||||
new_node->next = NULL;
|
||||
return(head);
|
||||
}
|
||||
|
||||
// Given an input id search list until id found
|
||||
// return lval of that *node value otherwise return a NULL value
|
||||
node *find_id( node *head, u32 id)
|
||||
{
|
||||
if( head == NULL) {
|
||||
return( head);
|
||||
}
|
||||
node *iterator = head;
|
||||
|
||||
while(( iterator != NULL) && ( iterator->id != id)) { // search and compare id
|
||||
iterator = iterator->next;
|
||||
}
|
||||
return( iterator);
|
||||
}
|
||||
|
||||
// Given an id, find it with the function above and then use node* value (target)
|
||||
// to create a gap of previous and next nodes which is then closed.
|
||||
// if id is not found nothing happens
|
||||
node *remove_node_by_id( node *head, u32 id)
|
||||
{
|
||||
node *target = NULL;
|
||||
|
||||
target = find_id( head, id);
|
||||
if( target == NULL) {
|
||||
return( head);
|
||||
}
|
||||
head = zip_list( head, target);
|
||||
free_node( target);
|
||||
return( head);
|
||||
}
|
||||
|
||||
// Given a specific lval node* target value, remove it from the list *head
|
||||
// and then close the gap created by removing target.
|
||||
node *zip_list( node *head, node* target)
|
||||
{
|
||||
bool has_previous = true;
|
||||
bool has_next = true;
|
||||
|
||||
if( target == NULL) {
|
||||
return( head);
|
||||
}
|
||||
if( target->previous == NULL) {
|
||||
has_previous = false;
|
||||
#ifdef KDEBUG
|
||||
kprint("has_previous FALSE\n");
|
||||
#endif
|
||||
}
|
||||
if ( target->next == NULL) {
|
||||
has_next = false;
|
||||
#ifdef KDEBUG
|
||||
kprint("has_next FALSE\n");
|
||||
#endif
|
||||
}
|
||||
if( (has_next == true) && (has_previous == true)) { // Node in middle of chain
|
||||
target->previous->next = target->next;
|
||||
target->next->previous = target->previous;
|
||||
} else if ( (has_next == false && has_previous == true)) { // Node at end of chain
|
||||
target->previous->next = NULL;
|
||||
} else if ( (has_next == true && has_previous == false)) { // Node at start of chain
|
||||
target->next->previous = NULL;
|
||||
head = head->next;
|
||||
} else { // ( has_next == false && has_previous == false) // Node is isolated
|
||||
head = NULL;
|
||||
}
|
||||
return(head);
|
||||
}
|
||||
|
||||
// Use find_id to get the insert_point
|
||||
// decide if insertion is before or after
|
||||
// if ft_before_after = FALSE then insert before target
|
||||
// if ft_before_after = TRUE then append after target
|
||||
node *insert_node( node *head, node* insert_point, node *new_node, bool ft_before_after)
|
||||
{
|
||||
if( new_node == NULL) { // Nothing to add so return unchanged
|
||||
return( head);
|
||||
}
|
||||
if( insert_point == NULL) { // If no point specified either place before head or after tail
|
||||
if( ft_before_after) { // if after is set append as new tail
|
||||
head = append_node( head, new_node);
|
||||
} else { // if before than insert before head as new head
|
||||
new_node->next = head;
|
||||
new_node->previous = NULL;
|
||||
head-> previous = new_node;
|
||||
return( new_node); // return new head
|
||||
}
|
||||
return( head);
|
||||
}
|
||||
|
||||
if( ft_before_after) { // if adding after then...
|
||||
if( insert_point->next != NULL) { // insert node after insertion_point
|
||||
insert_point->next->previous = new_node;
|
||||
new_node->next = insert_point->next;
|
||||
} else { // insertion point is last node instead, skip above operations
|
||||
new_node->next = NULL;
|
||||
}
|
||||
new_node->previous = insert_point;
|
||||
insert_point->next = new_node;
|
||||
} else {
|
||||
if( insert_point->previous != NULL) { // insert node before insertion point
|
||||
insert_point->previous->next = new_node;
|
||||
new_node->previous = insert_point->previous;
|
||||
} else { // insertion point is head
|
||||
new_node->previous = NULL;
|
||||
head = new_node; // set new head as insertion point
|
||||
}
|
||||
insert_point->previous = new_node;
|
||||
new_node->next = insert_point;
|
||||
}
|
||||
return(head); // return changes (if any) to head
|
||||
}
|
||||
|
||||
node *get_tail( node *head)
|
||||
{
|
||||
if( head == NULL) {
|
||||
return(head);
|
||||
}
|
||||
node *tail = head;
|
||||
while( tail->next != NULL) { // iterate until the next node is not NULL
|
||||
tail = tail->next;
|
||||
}
|
||||
return( tail);
|
||||
}
|
||||
|
||||
void get_min_max_id( node *head, u32 *min, u32 *max)
|
||||
{
|
||||
if( head == NULL) {
|
||||
return;
|
||||
}
|
||||
node *iterator = head;
|
||||
*min = 0xFFFFFFFF;
|
||||
*max = 0;
|
||||
|
||||
while( iterator != NULL) { // iterate until the next node is not NULL
|
||||
if( *min > iterator->id) {
|
||||
*min = iterator->id;
|
||||
}
|
||||
if( *max < iterator->id) {
|
||||
*max = iterator->id;
|
||||
}
|
||||
iterator = iterator->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void swap_node_data( node* left, node *right)
|
||||
{
|
||||
if(( left == NULL) || (right == NULL)) {
|
||||
kprint("Invalid element.\n");
|
||||
return;
|
||||
}
|
||||
node swap;
|
||||
|
||||
kprint_hex("SWAP ", left->id, 4);
|
||||
kprint_hex(" with ", right->id, 4);
|
||||
kprint("\n");
|
||||
|
||||
swap.id = left->id;
|
||||
swap.base_register = left->base_register;
|
||||
swap.limit_register = left->limit_register;
|
||||
swap.ft_hole_mem = left->ft_hole_mem;
|
||||
|
||||
left->id = right->id;
|
||||
left->base_register = right->base_register;
|
||||
left->limit_register = right->limit_register;
|
||||
left->ft_hole_mem = right->ft_hole_mem;
|
||||
|
||||
right->id = swap.id;
|
||||
right->base_register = swap.base_register;
|
||||
right->limit_register = swap.limit_register;
|
||||
right->ft_hole_mem = swap.ft_hole_mem;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
node *swap_nodes( node *head, node** left, node **right)
|
||||
{
|
||||
|
||||
if( head == NULL) { // don't swap nodes in a list that is empty
|
||||
return( head);
|
||||
}
|
||||
|
||||
if( (*left == NULL) || (*right == NULL) ) { // if either or both nodes are NULL do nothing
|
||||
return( head);
|
||||
}
|
||||
if ( head == *left) { // if left happens to be head than set head to right
|
||||
head = *right;
|
||||
}
|
||||
if ( head == *right) { // if right happens to be head then set head to left
|
||||
head = *left;
|
||||
}
|
||||
|
||||
node *left_previous = (*left)->previous;
|
||||
node *left_next = (*left)->next;
|
||||
node *right_previous = (*right)->previous;
|
||||
node *right_next = (*right)->next;
|
||||
|
||||
if( (*left)->previous != NULL) { // make sure not to access a NULL value node
|
||||
(*left)->previous->next = *right; // previous node to left now points to right instead of left
|
||||
}
|
||||
|
||||
if( (*left)->next != NULL) { // same
|
||||
(*left)->next->previous = *right; // next node to left now points to right instead of left
|
||||
}
|
||||
|
||||
if( (*right)->previous != NULL) { // same
|
||||
(*right)->previous->next = *left; // same as above but right previous to left now
|
||||
}
|
||||
if( (*right)->next != NULL) { // same
|
||||
(*right)->next->previous = *left; // same as above...
|
||||
}
|
||||
|
||||
(*left)->previous = right_previous; // this will obliterate left->previous so it is preserved in left_previous
|
||||
(*left)->next = right_next; // this will obliterate left->next so it is preserved in left_next
|
||||
|
||||
(*right)->previous = left_previous; // now point right node back to previous to left node (obliterated above)
|
||||
(*right)->next = left_next; // now point right node forward to next of left node (obliterated above)
|
||||
|
||||
node* swap;
|
||||
swap = *left;
|
||||
*left = *right;
|
||||
*right = swap;
|
||||
|
||||
#ifdef KDEBUG
|
||||
kprint("LEFT: ");
|
||||
print_node( *left);
|
||||
kprint(" RIGHT: ");
|
||||
print_node( *right);
|
||||
kprint("\n");
|
||||
#endif
|
||||
|
||||
return( head); // return new head if it changed
|
||||
}
|
||||
|
||||
// good ways to sort a list, transfer it to an array and merge or quicksort it
|
||||
// not so good bubble-sort, insertion, select-sort, heap-sort
|
||||
// worst, this ugly hack
|
||||
node *hacksort_list( node* head, bool ft_descending_ascending)
|
||||
{
|
||||
if( head == NULL) {
|
||||
kprint("LIST EMPTY\n");
|
||||
return(head);
|
||||
}
|
||||
if( ft_descending_ascending) {
|
||||
kprint("ASCENDING\n");
|
||||
} else {
|
||||
kprint("DESCENDING\n");
|
||||
}
|
||||
node* outer_iterator = head;
|
||||
node* inner_iterator = head->next;
|
||||
node* max = head;
|
||||
|
||||
while( outer_iterator != NULL) {
|
||||
max = outer_iterator;
|
||||
inner_iterator = outer_iterator->next;
|
||||
while( inner_iterator != NULL) {
|
||||
if( ft_descending_ascending) {
|
||||
if( max->id > inner_iterator->id) { // This decides ASCENDING
|
||||
max = inner_iterator;
|
||||
}
|
||||
} else {
|
||||
if( max->id < inner_iterator->id) { // This decides SORT DESCENDING
|
||||
max = inner_iterator;
|
||||
}
|
||||
}
|
||||
inner_iterator = inner_iterator->next;
|
||||
/******* STOP COUNTER for Infnite Loop Halting
|
||||
u32 count = 0;
|
||||
if( count++ > 10) {
|
||||
return(head);
|
||||
}
|
||||
****/
|
||||
}
|
||||
if( ( outer_iterator != NULL) && ( outer_iterator != max)) {
|
||||
swap_node_data( outer_iterator, max);
|
||||
}
|
||||
outer_iterator = outer_iterator->next;
|
||||
}
|
||||
return( head);
|
||||
}
|
||||
|
||||
node *mergesort_list( node* head, node *pivot, node *left, node *right)
|
||||
{
|
||||
return( head); // disabled, not yet implemented
|
||||
if( ( head == NULL) || ( pivot == NULL) | ( left == NULL) | ( right == NULL)) {
|
||||
return( head);
|
||||
}
|
||||
node *start = left;
|
||||
node *end = right;
|
||||
while( (start->next != NULL) || (start->id != end->id)) {
|
||||
if( start->id < pivot->id) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
return( head);
|
||||
}
|
||||
|
||||
// stand in for delete, this only zeroes all the values of the node allocated by kmalloc
|
||||
// the memory is not reclaimed, need to add a tracker for these kmalloc allocated blocks
|
||||
// to implement a proper delete function
|
||||
void free_node( node *target)
|
||||
{
|
||||
memory_set( (u8 *) target, 0, NODE_SIZE);
|
||||
target = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Print a single node's values
|
||||
void print_node( node *current)
|
||||
{
|
||||
char numstr[16];
|
||||
|
||||
if( current->previous != NULL) {
|
||||
kprint_hex( "(", current->previous->id, 4);
|
||||
kprint( ")<-");
|
||||
} else {
|
||||
kprint("NULL<-");
|
||||
}
|
||||
|
||||
memory_set( (u8 *) numstr, 0, 16);
|
||||
hex_to_ascii( current->id, numstr, 16);
|
||||
kprint("ID: "); kprint( numstr); kprint(" --- ");
|
||||
memory_set( (u8 *) numstr, 0, 16);
|
||||
hex_to_ascii( current->base_register, numstr, 16);
|
||||
kprint("BASE: "); kprint( numstr); kprint(" --- ");
|
||||
memory_set( (u8 *) numstr, 0, 16);
|
||||
hex_to_ascii( current->limit_register, numstr, 16);
|
||||
kprint("LIMIT: "); kprint( numstr); kprint(" --- ");
|
||||
if( current->ft_hole_mem) {
|
||||
kprint("MEMORY ");
|
||||
} else {
|
||||
kprint("HOLE ");
|
||||
}
|
||||
if( current->next != NULL) {
|
||||
kprint_hex( "->", current->next->id, 4);
|
||||
} else {
|
||||
kprint("->NULL");
|
||||
}
|
||||
kprint("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// just print the id separated by commas with a line-feed at the end
|
||||
void shortprint_list( node *head, bool ft_descending_ascending)
|
||||
{
|
||||
if( head == NULL) {
|
||||
kprint( "EMPTY.");
|
||||
kprint("\n");
|
||||
return;
|
||||
}
|
||||
node *iterator = NULL;
|
||||
if( ft_descending_ascending) {
|
||||
iterator = head;
|
||||
while( iterator != NULL) {
|
||||
kprint_hex( ",",iterator->id, 4);
|
||||
iterator = iterator->next;
|
||||
}
|
||||
} else {
|
||||
iterator = get_tail( head);
|
||||
while( iterator != NULL) {
|
||||
kprint_hex( ",",iterator->id, 4);
|
||||
iterator = iterator->previous;
|
||||
}
|
||||
}
|
||||
kprint("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate through a list printing out the values of each node
|
||||
void print_list( node *head, bool ft_descending_ascending)
|
||||
{
|
||||
if( head == NULL) {
|
||||
kprint( "EMPTY.");
|
||||
return;
|
||||
}
|
||||
node *iterator = NULL;
|
||||
if( ft_descending_ascending) {
|
||||
iterator = head;
|
||||
while( iterator != NULL) {
|
||||
print_node( iterator);
|
||||
iterator = iterator->next;
|
||||
}
|
||||
} else {
|
||||
iterator = get_tail( head);
|
||||
while( iterator != NULL) {
|
||||
print_node( iterator);
|
||||
iterator = iterator->previous;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
27
Part3/09_memory/libc/linked.h
Normal file
27
Part3/09_memory/libc/linked.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef LINKED_H
|
||||
#define LINKED_H
|
||||
|
||||
#include "../cpu/types.h"
|
||||
#include "globals.h"
|
||||
#include "mem.h"
|
||||
|
||||
node *create_node( u32 base_register, u32 limit_register, bool ft_hole_mem, u32 id);
|
||||
node *add_node( node *head, u32 base_register, u32 limit_register, bool ft_hole_mem, u32 id);
|
||||
node *_add_node( node *head, node *new_node);
|
||||
node *append_node( node *head, node* new_node);
|
||||
node *find_id( node *head, u32 id);
|
||||
node *remove_node_by_id( node *head, u32 id);
|
||||
node *zip_list( node *head, node* target);
|
||||
node *insert_node( node *head, node* insert_point, node *new_node, bool ft_before_after);
|
||||
node *get_tail( node *head);
|
||||
void get_min_max_id( node *head, u32 *min, u32 *max);
|
||||
node *swap_nodes( node *head, node **left, node **right);
|
||||
void swap_node_data( node* left, node *right);
|
||||
node *hacksort_list( node* head, bool ft_backward_forward);
|
||||
node *mergesort_list( node* head, node *pivot, node *left, node *right);
|
||||
void free_node( node *target);
|
||||
void print_node( node *current);
|
||||
void print_list( node *head, bool ft_backward_forward);
|
||||
void shortprint_list( node *head, bool ft_backward_forward);
|
||||
|
||||
#endif
|
76
Part3/09_memory/libc/mem.c
Normal file
76
Part3/09_memory/libc/mem.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "mem.h"
|
||||
|
||||
void memory_copy(u8 *source, u8 *dest, int nbytes) {
|
||||
int i;
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
*(dest + i) = *(source + i);
|
||||
}
|
||||
}
|
||||
|
||||
void memory_set(u8 *dest, u8 val, u32 len) {
|
||||
u8 *temp = (u8 *)dest;
|
||||
for ( ; len != 0; len--) *temp++ = val;
|
||||
}
|
||||
|
||||
// See globals.h for kmem_addr global declaration
|
||||
// kmem_addr is reserved block of memory for kernel to store linked list nodes
|
||||
/* Implementation is just a pointer to some free memory which
|
||||
* keeps growing */
|
||||
u32 kmalloc(u32 size, int align, u32 *phys_addr) {
|
||||
/* Pages are aligned to 4K, or 0x1000 */
|
||||
if (align == 1 && (kmem_addr & 0xFFFFF000)) {
|
||||
kmem_addr &= 0xFFFFF000;
|
||||
kmem_addr += 0x1000;
|
||||
}
|
||||
|
||||
|
||||
char c[16];
|
||||
hex_to_ascii( *phys_addr, c, 16);
|
||||
kprint("Inside kmalloc phys_addr (before) = ");
|
||||
kprint(c);
|
||||
kprint(" --- ");
|
||||
|
||||
/* Save the physical address */
|
||||
*phys_addr = kmem_addr;
|
||||
|
||||
hex_to_ascii( *phys_addr, c, 16);
|
||||
kprint("(after) phys_addr = ");
|
||||
kprint(c);
|
||||
kprint("\n");
|
||||
|
||||
u32 ret = kmem_addr;
|
||||
kmem_addr += size; /* Remember to increment the pointer */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// See globals.h for user_start global declaration
|
||||
// umem_addr is reserved block of memory for kernel to store linked list nodes
|
||||
/* Implementation is just a pointer to some free memory which
|
||||
* keeps growing */
|
||||
u32 umalloc(u32 size, int align, u32 *phys_addr) {
|
||||
/* Pages are aligned to 4K, or 0x1000 */
|
||||
if (align == 1 && (umem_addr & 0xFFFFF000)) {
|
||||
umem_addr &= 0xFFFFF000;
|
||||
umem_addr += 0x1000;
|
||||
}
|
||||
|
||||
|
||||
char c[16];
|
||||
hex_to_ascii( *phys_addr, c, 16);
|
||||
kprint("Inside umalloc phys_addr (before) = ");
|
||||
kprint(c);
|
||||
kprint(" --- ");
|
||||
|
||||
/* Save the physical address */
|
||||
*phys_addr = umem_addr;
|
||||
|
||||
hex_to_ascii( *phys_addr, c, 16);
|
||||
kprint("(after) phys_addr = ");
|
||||
kprint(c);
|
||||
kprint("\n");
|
||||
|
||||
u32 ret = umem_addr;
|
||||
umem_addr += size; /* Remember to increment the pointer */
|
||||
return ret;
|
||||
}
|
15
Part3/09_memory/libc/mem.h
Normal file
15
Part3/09_memory/libc/mem.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef MEM_H
|
||||
#define MEM_H
|
||||
|
||||
#include "../cpu/types.h"
|
||||
#include "../libc/string.h"
|
||||
#include "../drivers/screen.h"
|
||||
#include "globals.h"
|
||||
|
||||
void memory_copy(u8 *source, u8 *dest, int nbytes);
|
||||
void memory_set(u8 *dest, u8 val, u32 len);
|
||||
|
||||
u32 kmalloc(u32 size, int align, u32 *phys_addr);
|
||||
u32 umalloc(u32 size, int align, u32 *phys_addr);
|
||||
|
||||
#endif
|
112
Part3/09_memory/libc/string.c
Normal file
112
Part3/09_memory/libc/string.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "string.h"
|
||||
|
||||
/**
|
||||
* K&R implementation
|
||||
*/
|
||||
void int_to_ascii(int n, char str[], int size) {
|
||||
memory_set( (u8 *) str, 0, size);
|
||||
int i, sign;
|
||||
if ((sign = n) < 0) n = -n;
|
||||
i = 0;
|
||||
do {
|
||||
str[i++] = n % 10 + '0';
|
||||
} while ((n /= 10) > 0);
|
||||
|
||||
if (sign < 0) str[i++] = '-';
|
||||
str[i] = '\0';
|
||||
|
||||
reverse(str);
|
||||
}
|
||||
|
||||
// Convert the numeric value n to a character string of 0x#...# where # is hexadecimal values
|
||||
// Size is the size of the char str[] array so number of hex digits is 1 less than size
|
||||
// because you need a terminating 0
|
||||
// the char str[] is erased with 0 values at start.
|
||||
void hex_to_ascii(int n, char str[], int size) {
|
||||
memory_set( (u8 *) str, 0, size);
|
||||
append(str, '0');
|
||||
append(str, 'x');
|
||||
char zeros = 0;
|
||||
|
||||
s32 tmp;
|
||||
int i;
|
||||
|
||||
for (i = 28; i > 0; i -= 4) {
|
||||
tmp = (n >> i) & 0xF;
|
||||
if (tmp == 0 && zeros == 0) continue;
|
||||
zeros = 1;
|
||||
if (tmp >= 0xA) append(str, tmp - 0xA + 'A');
|
||||
else append(str, tmp + '0');
|
||||
}
|
||||
|
||||
tmp = n & 0xF;
|
||||
if (tmp >= 0xA) append(str, tmp - 0xA + 'A');
|
||||
else append(str, tmp + '0');
|
||||
}
|
||||
|
||||
/* K&R */
|
||||
void reverse(char s[]) {
|
||||
int c, i, j;
|
||||
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
|
||||
c = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = c;
|
||||
}
|
||||
}
|
||||
|
||||
/* K&R */
|
||||
int strlen(char s[]) {
|
||||
int i = 0;
|
||||
while (s[i] != '\0') ++i;
|
||||
return i;
|
||||
}
|
||||
|
||||
// not K&R
|
||||
int sstrlen( char s[], u32 size)
|
||||
{
|
||||
if( size <= 0) {
|
||||
return(0);
|
||||
}
|
||||
u32 i = 0;
|
||||
while ( (s[i] != '\0') && ( i < size)) { ++i; }
|
||||
return( i);
|
||||
}
|
||||
|
||||
void append(char s[], char n) {
|
||||
int len = strlen(s);
|
||||
s[len] = n;
|
||||
s[len+1] = '\0';
|
||||
}
|
||||
|
||||
void backspace(char s[]) {
|
||||
int len = strlen(s);
|
||||
s[len-1] = '\0';
|
||||
}
|
||||
|
||||
/* K&R
|
||||
* Returns <0 if s1<s2, 0 if s1==s2, >0 if s1>s2 */
|
||||
int strcmp(char s1[], char s2[]) {
|
||||
int i;
|
||||
for (i = 0; s1[i] == s2[i]; i++) {
|
||||
if (s1[i] == '\0') return 0;
|
||||
}
|
||||
return s1[i] - s2[i];
|
||||
}
|
||||
|
||||
// Not K&R
|
||||
// Compare strings for first size characters
|
||||
// if size > both string sizes compare whole string
|
||||
int strncmp( char s1[], char s2[], u32 size)
|
||||
{
|
||||
u32 i = 0;
|
||||
while( (s1[i] != '\0') && (s2[i] != '\0') && (i < size) && (s1[i] == s2[i])) {
|
||||
++i;
|
||||
}
|
||||
if(i >= size) { // match exceeded size, they are same up to size chars
|
||||
return(0);
|
||||
} else if ( (s1[i] == s2[i])) { // match ended before size are they same? (includeing NULL matches)
|
||||
return(0);
|
||||
} // else don't match return diff
|
||||
return( s1[i] - s2[i]);
|
||||
}
|
||||
|
17
Part3/09_memory/libc/string.h
Normal file
17
Part3/09_memory/libc/string.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef STRINGS_H
|
||||
#define STRINGS_H
|
||||
|
||||
#include "../cpu/types.h"
|
||||
#include "mem.h"
|
||||
|
||||
void int_to_ascii(int n, char str[], int size);
|
||||
void hex_to_ascii(int n, char str[], int size);
|
||||
void reverse(char s[]);
|
||||
int strlen(char s[]);
|
||||
void backspace(char s[]);
|
||||
void append(char s[], char n);
|
||||
int strcmp(char s1[], char s2[]);
|
||||
int strncmp(char s1[], char s2[], u32 size);
|
||||
int sstrlen( char s1[], u32 size);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user