This repository has been archived on 2024-01-18. You can view files and clone it, but cannot push or open issues or pull requests.
OS_Project/Part3/09_memory/kernel/kernel.c

296 lines
10 KiB
C
Raw Normal View History

#include "kernel.h"
2023-10-18 18:04:33 +00:00
// This only runs once and from there on forth only interrupts will cause something to happen
// e.g. displaying to screen and taking input from keyboard
void _start() {
// Initialize Global Variables and set up interrrupt handlers
// These variables are a vulnerability to OS security if someone can adjust
// the lower value in the kernel code (exploiting, for example, an Intel address hack)
// than kernel memory and even kernel code can be overwritten
// https://www.wired.com/story/intel-lab-istare-hack-chips/
// See libc/globals.h for KMEM_START and KMEM_END values
// See libc/globals.h for UMEM_START and UMEM_END values
kmem_addr = KMEM_START;
kernel_mem_limit = KMEM_END;
2023-10-18 18:04:33 +00:00
umem_addr = UMEM_START;
user_mem_limit = UMEM_END;
2023-10-18 18:04:33 +00:00
global_head = NULL;
global_id = 0;
2023-10-18 18:04:33 +00:00
isr_install();
irq_install();
2023-10-18 18:04:33 +00:00
kprint("Type something, it will go through the kernel\n"
"Type HELP to list commands\n> ");
}
2023-10-18 18:04:33 +00:00
// An interrupt calls this function to parse what was typed in, this is, essentially, your
// Command Line Interpreter for now.
void user_input(char *input) {
static u32 delete_id = 0; // static persistent variable for incrementing during test
static node* umem_head = NULL; // static persistent head variable for contiguous block allocations
if (strcmp(input, "END") == 0) {
kprint("Stopping the CPU. Bye!\n");
asm volatile("hlt");
} else if (strncmp(input, "ADD", 3) == 0) {
2023-11-29 15:07:20 +00:00
u32 base = 0x10000;
u32 limit = 0x100;
bool valid = true;
if (sstrlen(input, 15) > 4) {
2023-11-29 15:07:20 +00:00
char *args1 = input + 4;
base = digit_conver(args1);
int nDigits = digit_len(base);
if (sstrlen(args1, 15) > nDigits + 1) {
2023-11-29 15:15:42 +00:00
char *args2 = args1 + nDigits + 1;
2023-11-29 15:07:20 +00:00
limit = digit_conver(args2);
2023-11-29 14:56:07 +00:00
}
2023-11-29 15:07:20 +00:00
if (base < 10000) {
2023-11-29 15:12:40 +00:00
kprint("That memory address is reserved by the Kernel, addresses must be 10000+\n");
2023-11-29 15:07:20 +00:00
valid = false;
}
2023-11-29 15:07:20 +00:00
}
if (valid) {
2023-11-30 00:15:38 +00:00
umem_head = add_node( umem_head, base, limit-1, true, global_id++);
}
} else if (strcmp(input, "LIST") == 0) {
kprint("***** FORWARD ****\n");
print_list( umem_head, true);
kprint("***** REVERSE ****\n");
print_list( umem_head, false);
} else if (strcmp(input, "SHORTLIST") == 0) {
shortprint_list( umem_head, true);
kprint("\n******************\n");
shortprint_list( umem_head, false);
} else if (strcmp(input, "PAGE") == 0) {
u32 phys_addr = 0;
u32 page = umalloc(0x4200, 0, &phys_addr);
kprint_hex( "Page: ", page, 10);
kprint_hex(", physical address: ", phys_addr, 10);
kprint("\n");
} else if (strcmp(input, "DELETE") == 0) {
umem_head = remove_node_by_id( umem_head, delete_id++);
} else if (strcmp(input, "INSERT") == 0) {
node *new_node = create_node( 0x15000, 0x1100, true, global_id++);
node *insert_point = find_id( umem_head, 3);
umem_head = insert_node( umem_head, insert_point, new_node, true);
new_node = create_node( 0x18000, 0x2100, true, global_id++);
insert_point = find_id( umem_head, 5);
umem_head = insert_node( umem_head, insert_point, new_node, false);
} else if (strcmp(input, "SORTA") == 0) {
umem_head = hacksort_list( umem_head, true);
} else if (strcmp(input, "SORTD") == 0) {
umem_head = hacksort_list( umem_head, false);
} else if (strcmp(input, "SWAP") == 0) {
node *n1 = find_id( umem_head, 1);
node *n2 = find_id( umem_head, 5);
node *n3 = find_id( umem_head, 3);
node *n4 = find_id( umem_head, 7);
swap_node_data( n1, n2);
swap_node_data( n2, n3);
swap_node_data( n3, n4);
} else if (strcmp(input, "TEST") == 0) {
char s1[10] = "ABCDFFGH\0";
char s2[10] = "ABCDEGH\0";
int x = strncmp( s1, s2, 5);
kprint_hex( "STRNCMP: ", x, 16);
kprint("\n");
x = sstrlen( s2, 10);
kprint_hex( "SSTRLEN: ", x, 10);
kprint("\n");
x = strlen( s2);
kprint_hex( "STRLEN: ", x, 10);
kprint("\n");
} else if (strcmp(input, "HELP") == 0) {
kprint("Current Commands: ADD, LIST, SHORTLIST, PAGE, DELETE,\n");
kprint(" : END, INSERT, SORTA, SORTD, SWAP, TEST, HELP\n");
kprint(" Review the kernel.c source code to see what each command does.\n");
kprint(" These are hard coded and are just examples, modify as you see fit.\n");
kprint(" for example - TEST was just added so that I could test the strlen commands.\n");
2023-11-29 21:33:10 +00:00
} else if (strcmp(input, "HOLES") == 0) {
2023-11-30 00:21:24 +00:00
node *holes = get_holes(umem_head);
print_list( holes, false);
2023-11-30 00:15:38 +00:00
} else if (strcmp(input, "RESULT") == 0) {
node *holes = get_holes( umem_head);
print_memory( umem_head, holes);
2023-11-30 02:52:46 +00:00
} else if (strcmp(input, "START") == 0) {
begin_output_example();
} else {
kprint("You said: ");
kprint(input);
kprint("\n");
}
kprint("> ");
2023-10-18 18:04:33 +00:00
}
2023-11-29 13:06:18 +00:00
2023-11-29 14:58:22 +00:00
int digit_len(unsigned digit) {
2023-11-29 14:59:14 +00:00
if (digit >= 1000000000) return 10;
if (digit >= 100000000) return 9;
if (digit >= 10000000) return 8;
if (digit >= 1000000) return 7;
if (digit >= 100000) return 6;
if (digit >= 10000) return 5;
if (digit >= 1000) return 4;
if (digit >= 100) return 3;
if (digit >= 10) return 2;
2023-11-29 14:58:22 +00:00
return 1;
}
2023-11-29 13:56:15 +00:00
int digit_conver(const char *hexString) {
2023-11-29 13:49:02 +00:00
u32 result = 0;
while (*hexString != '\0') {
char hexChar = *hexString;
if ((hexChar >= '0' && hexChar <= '9') || (hexChar >= 'A' && hexChar <= 'F')) {
int digit = (hexChar >= '0' && hexChar <= '9') ? (hexChar - '0') : (10 + (hexChar - 'A'));
result = result * 16 + digit;
} else {
2023-11-29 14:56:07 +00:00
break;
}
2023-11-29 13:49:02 +00:00
hexString++;
2023-11-29 13:06:18 +00:00
}
return result;
2023-11-29 13:06:18 +00:00
}
2023-11-29 19:16:15 +00:00
2023-11-30 00:15:38 +00:00
void print_memory(node *umem_head, node *hole_head) {
u32 total_memory = 0x3FFFF;
2023-11-30 01:35:42 +00:00
u32 free_memory = total_memory;
int num_of_gaps = 0;
int num_of_nodes = 0;
while (umem_head != NULL) {
num_of_nodes++;
free_memory = free_memory - umem_head->limit_register;
umem_head = umem_head->next;
}
while (hole_head != NULL) {
num_of_gaps++;
2023-11-30 01:44:19 +00:00
hole_head = hole_head->next;
2023-11-30 01:35:42 +00:00
}
2023-11-30 00:15:38 +00:00
2023-11-30 01:46:14 +00:00
u32 total_allocated = total_memory - free_memory;
2023-11-30 02:03:52 +00:00
total_memory = (total_memory+1)/(0x400);
2023-11-30 01:43:19 +00:00
char a[16];
2023-11-30 02:03:52 +00:00
int_to_ascii( total_memory-64, a, 16);
2023-11-30 02:02:33 +00:00
kprint("\nTotal Physical Memory: ");
2023-11-30 01:43:19 +00:00
kprint(a);
kprint("kb\n");
2023-11-30 02:03:52 +00:00
free_memory = (free_memory+1)/(0x400);
2023-11-30 01:43:19 +00:00
char b[16];
2023-11-30 02:05:18 +00:00
int_to_ascii( free_memory-64, b, 16);
2023-11-30 01:43:19 +00:00
kprint("Total Free: ");
kprint(b);
kprint("kb\n");
2023-11-30 02:03:52 +00:00
total_allocated = (total_allocated+1)/(0x400);
2023-11-30 01:43:19 +00:00
char c[16];
2023-11-30 02:51:46 +00:00
int_to_ascii( total_allocated, c, 16);
2023-11-30 01:43:19 +00:00
kprint("Total Allocated: ");
2023-11-30 00:15:38 +00:00
kprint(c);
2023-11-30 01:35:42 +00:00
kprint("kb\n");
2023-11-30 00:17:52 +00:00
2023-11-30 01:43:19 +00:00
char d[16];
int_to_ascii( num_of_nodes, d, 16);
kprint("Number of Allocations: ");
kprint(d);
kprint("\n");
char e[16];
2023-11-30 01:48:46 +00:00
int_to_ascii( num_of_gaps, e, 16);
2023-11-30 01:43:19 +00:00
kprint("Number of Free Gaps: ");
kprint(e);
kprint("\n");
kprint("Start of Memory: 0x10000\nEnd of Memory: 0xFFFFF\n");
2023-11-30 00:15:38 +00:00
}
node* get_holes(node* umem_head) {
2023-11-29 22:50:25 +00:00
if (umem_head == NULL) {
2023-11-30 02:57:21 +00:00
node *hole = NULL;
hole = add_node(hole, 0x10000, 0x3FFFF, true, 0);
2023-11-30 02:51:46 +00:00
return hole;
2023-11-29 22:50:25 +00:00
}
2023-11-29 23:13:46 +00:00
u32 hole_ids = 0;
2023-11-29 23:06:25 +00:00
node *hole = NULL;
2023-11-29 23:24:19 +00:00
if (umem_head->base_register-0x10000 != 0) {
2023-11-30 00:15:38 +00:00
hole = add_node( hole, 0x10000, umem_head->base_register-0x10000-1, true, ++hole_ids);
2023-11-29 23:24:19 +00:00
}
2023-11-29 22:50:25 +00:00
while(umem_head != NULL) {
2023-11-29 23:24:19 +00:00
if (umem_head->next != NULL) {
node *next = umem_head->next;
2023-11-29 23:26:20 +00:00
u32 total = umem_head->base_register+umem_head->limit_register;
2023-11-30 00:15:38 +00:00
hole = add_node( hole, total, next->base_register-total-1, true, ++hole_ids);
2023-11-29 23:06:25 +00:00
} else {
2023-11-30 00:15:38 +00:00
hole = add_node( hole, umem_head->base_register+umem_head->limit_register-1, 0x3FFFF, true, ++hole_ids);
2023-11-29 22:50:25 +00:00
}
2023-11-29 23:06:25 +00:00
umem_head = umem_head->next;
2023-11-29 22:50:25 +00:00
}
2023-11-29 23:40:08 +00:00
return hole;
2023-11-30 02:51:46 +00:00
}
void begin_output_example() {
2023-11-30 02:55:25 +00:00
static node* umem_head = NULL; // static persistent head variable for contiguous block allocations
static node* holes_head = NULL;
2023-11-30 02:55:55 +00:00
holes_head = get_holes(umem_head);
2023-11-30 02:51:46 +00:00
// Display 1
2023-11-30 02:51:46 +00:00
kprint("Jonathan Turner - S02\n");
kprint("Current Allocation: \n");
print_memory(umem_head, holes_head);
umem_head = add_node( umem_head, 0x10000, 0x3FF, true, 0);
umem_head = add_node( umem_head, 0x11000, 0x1FF, true, 1);
umem_head = add_node( umem_head, 0x12000, 0x3FF, true, 2);
umem_head = add_node( umem_head, 0x15000, 0x7FF, true, 3);
umem_head = add_node( umem_head, 0x22000, 0x1FFF, true, 4);
2023-11-30 03:19:57 +00:00
// Display 2
print_memory(umem_head, holes_head);
node* temp = umem_head->next;
free_node(umem_head);
umem_head = temp;
umem_head->previous = NULL;
print_memory(umem_head, holes_head);
// print_list(umem_head, false);
// print_list(get_holes(umem_head), false);
2023-11-30 03:21:20 +00:00
// Display 3
temp = get_tail(umem_head);
free_node(temp);
print_memory(umem_head, holes_head);
// print_list(umem_head, false);
// print_list(get_holes(umem_head), false);
// Display 4
umem_head = add_node( umem_head, 0x23000, 0x1FFF, true, 5);
umem_head = add_node( umem_head, 0x25000, 0x3FFF, true, 6);
print_memory(umem_head, holes_head);
2023-11-30 03:23:10 +00:00
// print_list(umem_head, false);
// print_list(get_holes(umem_head), false);
2023-11-30 03:22:10 +00:00
// Display 5
temp = find_id(umem_head, 4);
node* previous = temp->previous;
previous->next = temp->next;
free_node(temp);
print_memory(umem_head, holes_head);
2023-11-30 03:21:20 +00:00
// print_list(umem_head, false);
// print_list(get_holes(umem_head), false);
2023-11-30 03:22:10 +00:00
// Display 6
2023-11-30 03:18:29 +00:00
// while (umem_head != NULL) {
// temp = umem_head->next;
// free_node(umem_head);
// umem_head = temp;
// }
// print_memory(umem_head, holes_head);
// // print_list(umem_head, false);
// // print_list(get_holes(umem_head), false);
// kprint("Jonathan Turner - S02");
2023-11-29 22:50:25 +00:00
}