Skip to content
Snippets Groups Projects
Commit 86498adf authored by Byron Lathi's avatar Byron Lathi
Browse files

Merge branch 'heap' into 'master'

Heap

See merge request bslathi19/summeros!1
parents e7a985c4 16db52ce
No related branches found
No related tags found
No related merge requests found
......@@ -14,7 +14,7 @@ ALL: $(SRC)
%.o: %.S
$(CC) $(CFLAGS) -c -Wall -o $@ $<
%: %.o syscall.o
%: %.o syscall.o lib.o
$(CC) $(LDFLAGS) -o $@ $^
mv $@ ../bin
......
#include "lib.h"
#include "syscall.h"
int32_t printf(int8_t *format, ...) {
/* Pointer to the format string */
int8_t* buf = format;
/* Stack pointer for the other parameters */
int32_t* esp = (void *)&format;
esp++;
while (*buf != '\0') {
switch (*buf) {
case '%':
{
int32_t alternate = 0;
buf++;
format_char_switch:
/* Conversion specifiers */
switch (*buf) {
/* Print a literal '%' character */
case '%':
putc('%');
break;
/* Use alternate formatting */
case '#':
alternate = 1;
buf++;
/* Yes, I know gotos are bad. This is the
* most elegant and general way to do this,
* IMHO. */
goto format_char_switch;
/* Print a number in hexadecimal form */
case 'x':
{
int8_t conv_buf[64];
if (alternate == 0) {
itoa(*((uint32_t *)esp), conv_buf, 16);
puts(conv_buf);
} else {
int32_t starting_index;
int32_t i;
itoa(*((uint32_t *)esp), &conv_buf[8], 16);
i = starting_index = strlen(&conv_buf[8]);
while(i < 8) {
conv_buf[i] = '0';
i++;
}
puts(&conv_buf[starting_index]);
}
esp++;
}
break;
/* Print a number in unsigned int form */
case 'u':
{
int8_t conv_buf[36];
itoa(*((uint32_t *)esp), conv_buf, 10);
puts(conv_buf);
esp++;
}
break;
/* Print a number in signed int form */
case 'd':
{
int8_t conv_buf[36];
int32_t value = *((int32_t *)esp);
if(value < 0) {
conv_buf[0] = '-';
itoa(-value, &conv_buf[1], 10);
} else {
itoa(value, conv_buf, 10);
}
puts(conv_buf);
esp++;
}
break;
/* Print a single character */
case 'c':
putc((uint8_t) *((int32_t *)esp));
esp++;
break;
/* Print a NULL-terminated string */
case 's':
puts(*((int8_t **)esp));
esp++;
break;
default:
break;
}
}
break;
default:
putc(*buf);
break;
}
buf++;
}
return (buf - format);
}
/* int32_t puts(int8_t* s);
* Inputs: int_8* s = pointer to a string of characters
* Return Value: Number of bytes written
* Function: Output a string to the console */
int32_t puts(int8_t* s) {
sys_write(1, s, strlen(s));
return strlen(s); // this is cap
}
/* void putc(uint8_t c);
* Inputs: uint_8* c = character to print
* Return Value: void
* Function: Output a character to the console */
void putc(uint8_t c) {
sys_write(1, &c, 1);
}
/* int8_t* itoa(uint32_t value, int8_t* buf, int32_t radix);
* Inputs: uint32_t value = number to convert
* int8_t* buf = allocated buffer to place string in
* int32_t radix = base system. hex, oct, dec, etc.
* Return Value: number of bytes written
* Function: Convert a number to its ASCII representation, with base "radix" */
int8_t* itoa(uint32_t value, int8_t* buf, int32_t radix) {
static int8_t lookup[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int8_t *newbuf = buf;
int32_t i;
uint32_t newval = value;
/* Special case for zero */
if (value == 0) {
buf[0] = '0';
buf[1] = '\0';
return buf;
}
/* Go through the number one place value at a time, and add the
* correct digit to "newbuf". We actually add characters to the
* ASCII string from lowest place value to highest, which is the
* opposite of how the number should be printed. We'll reverse the
* characters later. */
while (newval > 0) {
i = newval % radix;
*newbuf = lookup[i];
newbuf++;
newval /= radix;
}
/* Add a terminating NULL */
*newbuf = '\0';
/* Reverse the string and return */
return strrev(buf);
}
/* int8_t* strrev(int8_t* s);
* Inputs: int8_t* s = string to reverse
* Return Value: reversed string
* Function: reverses a string s */
int8_t* strrev(int8_t* s) {
register int8_t tmp;
register int32_t beg = 0;
register int32_t end = strlen(s) - 1;
while (beg < end) {
tmp = s[end];
s[end] = s[beg];
s[beg] = tmp;
beg++;
end--;
}
return s;
}
/* uint32_t strlen(const int8_t* s);
* Inputs: const int8_t* s = string to take length of
* Return Value: length of string s
* Function: return length of string s */
uint32_t strlen(const int8_t* s) {
register uint32_t len = 0;
while (s[len] != '\0')
len++;
return len;
}
#include "types.h"
int32_t printf(int8_t *format, ...);
void putc(uint8_t c);
int32_t puts(int8_t *s);
int8_t *itoa(uint32_t value, int8_t* buf, int32_t radix);
int8_t *strrev(int8_t* s);
uint32_t strlen(const int8_t* s);
void clear(void);
\ No newline at end of file
#include "syscall.h"
#include "lib.h"
int main(int argc, char** argv)
{
char argcs = argc + '0';
sys_write(1, &argcs, 1); // so that works
printf("Hi\n");
printf("Hi, %d\n", 1);
char* arg0 = argv[0]; // but this shouldn't
sys_write(1, arg0, 1);
int i;
for (i = 0; i < argc; i++) {
sys_write(1, "Arg: ", 4);
sys_write(1, argv[i], strlen(argv[i]));
sys_write(1, "\n", 1);
}
uint8_t test[64];
int ret;
......
#include <types.h>
#include <lib.h>
#include <Syscalls/execute.h>
#include <Filesystem/ext2.h>
#include "directory.h"
#include "filedescriptor.h"
......@@ -9,21 +10,28 @@ static fops_t directory_ops = {directory_open, directory_close, directory_read,
int32_t directory_read(int32_t fd, void* buf, int32_t len)
{
return -1;
}
int32_t directory_write(int32_t fd, const void* buf, int32_t len)
{
return -1;
}
int32_t directory_open(const uint8_t* name)
{
printf("directory_open\n");
return 2;
int32_t fd = find_new_fd();
pcb_t* pcb = get_pcb_ptr();
pcb->file_desc_array[fd].file_pos = 0;
pcb->file_desc_array[fd].flags |= FD_INUSE;
pcb->file_desc_array[fd].file_ops = &directory_ops;
pcb->file_desc_array[fd].inode = ext2_parse_path_to_inode_num((int8_t*)name);
return fd;
}
int32_t directory_close(int32_t fd)
{
return -1;
}
......@@ -52,7 +52,7 @@ uint32_t ext2_read_data(uint32_t inode_num, uint32_t count, uint16_t* buf)
for (i = 0; i < 12 && blocks_left != 0; i++) {
if (!inode.block_pointer[i])
break;
ata_read_sectors(ATA_MASTER, ext2_base + inode.block_pointer[i] * 2, 2, buf + i * 1024);
ata_read_sectors(ATA_MASTER, ext2_base + inode.block_pointer[i] * 2, 2, buf + i * 512);
blocks_left--;
}
......
......@@ -2,6 +2,7 @@
#include <lib.h>
#include <Syscalls/execute.h>
#include <Syscalls/syscalls.h>
#include <Filesystem/ext2.h>
#include "file.h"
#include "filedescriptor.h"
......@@ -10,12 +11,12 @@ static fops_t file_ops = {file_open, file_close, file_read, file_write};
int32_t file_read(int32_t fd, void* buf, int32_t len)
{
return -1;
}
int32_t file_write(int32_t fd, const void* buf, int32_t len)
{
return -1;
}
int32_t file_open(const uint8_t* name)
......@@ -34,5 +35,5 @@ int32_t file_open(const uint8_t* name)
int32_t file_close(int32_t fd)
{
return -1;
}
......@@ -13,4 +13,5 @@ int32_t find_new_fd()
return i;
}
}
return -1;
}
......@@ -4,6 +4,7 @@
#include <paging.h>
#include <Filesystem/ext2.h>
#include <Devices/terminal.h>
#include <heap.h>
#include "execute.h"
......@@ -86,8 +87,6 @@ int32_t _sys_exec(uint8_t* cmd)
printf("argc: %d\n", argc);
uint8_t* argv[argc];
// This will not work for arguments which need spaces
int i;
for (i = 0; i < cmdlen; i++) {
......@@ -95,26 +94,12 @@ int32_t _sys_exec(uint8_t* cmd)
cmd[i] = NULL;
}
//argv[0] = name;
tmpargs = cmd;
for (i = 0; i < argc; i++) {
while (*tmpargs == NULL) {
tmpargs++;
if (tmpargs - cmd > cmdlen)
break;
}
argv[i] = tmpargs;
while (*tmpargs) {
tmpargs++;
if (tmpargs - cmd > cmdlen)
break;
}
}
for (i = 0; i < argc; i++) {
printf("arg%d: %s\n", i, argv[i]);
printf("The first time... ");
for (i = 0; i < cmdlen; i++) {
printf("%c", cmd[i]);
//cmdcpy[i] = cmd[i];
}
printf("\n");
uint32_t parsed_inode = ext2_parse_path_to_inode_num((int8_t*)name);
......@@ -128,12 +113,6 @@ int32_t _sys_exec(uint8_t* cmd)
if (data.data8[EI_MAG2] != ELFMAG2) return EXEC_NOT_ELF;
if (data.data8[EI_MAG3] != ELFMAG3) return EXEC_NOT_ELF;
elf_header_t* header = (elf_header_t*)data.data8;
map_large(EXEC_BASE_ADDR, _8MB + pid * _4MB);
ext2_read_data(parsed_inode, 0, (uint16_t*)EXEC_LOAD_ADDR);
/* populate tss */
tss.ss0 = KERNEL_DS;
tss.esp0 = _8MB - _8KB*pid - 4;
......@@ -145,17 +124,54 @@ int32_t _sys_exec(uint8_t* cmd)
pcb->file_desc_array[0].file_ops = &stdin_ops;
pcb->file_desc_array[1].file_ops = &stdout_ops;
printf("Running a program with pid %d\n", pid);
heap_create(pid);
/* increment pid and run process; decrement it after termination */
pid++;
uint32_t status;
uint32_t* user_argc = (uint32_t*)0x83ffff8;
uint8_t*** user_argv = (uint8_t***)0x83ffffc;
// we need to allocate space for each of the pointers, then
// space for each of the arguments
uint8_t** argv = heap_alloc(sizeof(uint8_t*) * argc + cmdlen);
uint8_t* cmdcpy = (uint8_t*)((uint32_t)argv + sizeof(uint8_t*) * argc);
*user_argc = argc;
*user_argv = argv;
for (i = 0; i < cmdlen; i++) {
cmdcpy[i] = cmd[i];
}
tmpargs = cmdcpy;
for (i = 0; i < argc; i++) {
while (*tmpargs == NULL) {
tmpargs++;
if (tmpargs - cmdcpy > cmdlen)
break;
}
argv[i] = tmpargs;
while (*tmpargs) {
tmpargs++;
if (tmpargs - cmdcpy > cmdlen)
break;
}
}
printf("cmdcpy: %s\n", cmdcpy);
for (i = 0; i < argc; i++) {
printf("arg%d: %s\n", i, argv[i]);
}
elf_header_t* header = (elf_header_t*)data.data8;
map_large(EXEC_BASE_ADDR, _8MB + pid * _4MB);
ext2_read_data(parsed_inode, 0, (uint16_t*)EXEC_LOAD_ADDR);
*USER_ARGC = argc;
*USER_ARGV = argv;
pid++;
/* push use data segment, user stack pointer,
* flags, user code segment, entry point, then iret */
......@@ -181,11 +197,14 @@ int32_t _sys_exec(uint8_t* cmd)
pid--;
printf("end of _sys_exec\n");
return status;
}
int32_t _sys_exit(uint32_t status)
{
printf("_sys_exit\n");
pcb_t* pcb = get_pcb_ptr();
/* restart the shell if the user quits the last layer */
......@@ -196,8 +215,6 @@ int32_t _sys_exit(uint32_t status)
}
}
// unmap the current process memory before going back to the execute that called it
// remap original program memory
map_large(EXEC_BASE_ADDR, (_8MB + (get_pcb_ptr()->parent_pid)*_4MB));
tss.esp0 = pcb->parent_esp;
......
......@@ -11,6 +11,9 @@
#define EXEC_BASE_ADDR 0x08000000
#define EXEC_LOAD_ADDR 0x08048000
#define USER_ARGC (uint32_t*)0x83ffff8
#define USER_ARGV (uint8_t***)0x83ffffc
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
......
#include <types.h>
#include <lib.h>
#include "heap.h"
#include "paging.h"
uint32_t heap_create(int pid)
{
map_large(HEAP_START, HEAP_PHYS - pid * _4MB);
heap_header_t* header = (heap_header_t*)HEAP_START;
header->size = 1;
header->start = (heap_descriptor_t*)((uint32_t)header + sizeof(heap_header_t));
header->start->size = _4MB - sizeof(heap_header_t) - sizeof(heap_descriptor_t);
header->start->next = NULL;
header->start->prev = NULL;
header->start->flags &= ~HEAP_INUSE;
return 0;
}
uint32_t heap_destroy()
{
void* next = ((heap_header_t*)HEAP_START)->next_page;
unmap_large(HEAP_START);
// each process is guaranteed 1 large page, but other pages you need to figure out later
// We'll try to free them anyway, if they exist.
while (next) {
void* page = ((heap_header_t*)next)->next_page;
unmap_large((uint32_t)next);
next = page;
}
return 0;
}
void* heap_alloc(uint32_t size)
{
heap_descriptor_t* desc = ((heap_header_t*)HEAP_START)->start;
while (desc->flags & 1) {
desc = desc->next;
}
desc->flags |= HEAP_INUSE;
desc->next = (heap_descriptor_t*)((uint32_t)desc + size + sizeof(heap_descriptor_t));
return (void*)desc + sizeof(heap_descriptor_t);
}
uint32_t heap_free(void* addr)
{
return -1;
}
#ifndef _HEAP_H
#define _HEAP_H
#include <types.h>
#define HEAP_START 0x8800000
#define HEAP_PHYS 0x7000000
#define HEAP_INUSE 1
typedef struct heap_descriptor {
uint32_t size;
uint32_t flags;
struct heap_descriptor* prev;
struct heap_descriptor* next;
} heap_descriptor_t;
typedef struct heap_header {
uint32_t size;
void* next_page;
heap_descriptor_t* start;
} heap_header_t;
uint32_t heap_create(int pid);
uint32_t heap_destroy();
void* heap_alloc(uint32_t size);
uint32_t heap_free(void* addr);
#endif
\ No newline at end of file
......@@ -101,12 +101,14 @@ void entry(unsigned long magic, unsigned long addr) {
uint32_t fb_addr = mbi->framebuffer_info.framebuffer_addr_low;
// copy over mmap (can't just do 1 since its a linked list)
/*
int i;
uint8_t mmap[mbi->mmap_length];
for (i = 0; i < mbi->mmap_length; i++) {
mmap[i] = *((uint8_t*)mbi->mmap_addr + i);
}
uint32_t mmap_length = mbi->mmap_length;
*/
init_paging();
kmap_large(fb_addr, fb_addr);
......
......@@ -93,3 +93,19 @@ int32_t map_large(uint32_t v_addr, uint32_t p_addr)
return 0;
}
int32_t unmap_small(uint32_t v_addr);
int32_t unmap_large(uint32_t v_addr)
{
uint32_t dir_index = (uint32_t)v_addr >> DIR_BIT_OFF;
/* label as removed from page directory */
page_directory[dir_index].present = 0;
/* clear cache */
FLUSH_TLB();
return 0;
}
......@@ -73,8 +73,8 @@ void init_paging(void);
int32_t kmap_large(uint32_t v_addr, uint32_t p_addr);
int32_t map_large(uint32_t v_addr, uint32_t p_addr);
int32_t map_vmem(uint8_t** start);
int32_t unmap_small(uint32_t* v_addr);
int32_t unmap_large(uint32_t* v_addr);
int32_t unmap_small(uint32_t v_addr);
int32_t unmap_large(uint32_t v_addr);
#define FLUSH_TLB() asm volatile ("movl %%cr3, %%eax \n movl %%eax, %%cr3"::: "eax")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment