view src/os/shell.c @ 123:2a35ea7e123b

Moved the psw and registers into a program control block structure
author Jonathan Pevarnek <pevarnj@gmail.com>
date Thu, 23 Jun 2011 10:05:55 -0400
parents 967a56b96d13
children e2396f625db8
line wrap: on
line source

#include <std.h>
#include <string.h>
#include <stdio.h>
#include <error.h>
#include <die.h>
#include <os/fs.h>
#include <os/elf.h>
#include <os/psw.h>
#include <os/svc.h>
#include <os/scall.h>
#include <os/pcb.h>

#define PROGRAM_STACK_START 0x400000 - 160 //this is correct, ignore the documentation
#define KERNEL_STACK_START 0x380000 - 160 //this is correct, ignore the documentation

void start(u64 __memsize)
{
	char buffer[128];
	ErrCode err;
	init_all(__memsize);
	if(isError(init_fs(0x100, __memsize))) die();
	set_svc_handler(svc_handler, (void*)KERNEL_STACK_START);
	
	sPrint("SOS online!\n");
	while(1) {
		sPrint("$ ");
		sGet(buffer, 78);
		u32 fid;
		if(isError(err = lookupFile(buffer, &fid))) {
			if(errCode(err) == NOTFILE) sPrint("ERROR: command not found\n");
			continue;
		} else {
			u32 fileSize;
			if(isError(getFileSize(fid, &fileSize))) { //get the length of the file
				sPrint("ERROR: could not read file size\n");
				continue;
			}
			void *data = malloc(fileSize);
			if(!data) continue;
			if(isError(getFileData(fid, data))) goto loopCont;
			Elf64_Ehdr *eHdr = data;
			if(eHdr->e_ident[EI_MAG0] != ELFMAG0 || eHdr->e_ident[EI_MAG1] != ELFMAG1 ||
					eHdr->e_ident[EI_MAG2] != ELFMAG2 || eHdr->e_ident[EI_MAG3] != ELFMAG3)
				goto loopCont;
			if(eHdr->e_ident[EI_CLASS] != ELFCLASS64) goto loopCont;
			int i;
			for(i = 0; i < eHdr->e_phnum; i++) { //go through all the headers
				Elf64_Phdr *pHdr = ((Elf64_Phdr*)(data + eHdr->e_phoff) + i);
				if(pHdr->p_type == PT_LOAD) { //these segments get loaded into the memory
					void *fromLoc = data + pHdr->p_offset;
					void *toLoc = (void*)pHdr->p_vaddr;
					memcpy(toLoc, fromLoc, pHdr->p_filesz);
					size_t diff = pHdr->p_memsz - pHdr->p_filesz;
					if(diff) memset(toLoc + pHdr->p_filesz, 0, diff);
				}
			}

			PCB pcb;
			memset(&pcb, 0, sizeof(pcb));
			pcb.registers[15] = PROGRAM_STACK_START;
			pcb.psw.p = 1;
			pcb.psw.ea = 1;
			pcb.psw.ba = 1;
			pcb.psw.ptr = eHdr->e_entry;
			swapcontext_pcb(&shellPCB, &pcb);
		loopCont:
			free(data);
		}
	}
}