This commit is contained in:
p-w-rs
2022-09-07 11:18:56 -05:00
commit 7bb91e666d
121 changed files with 5306 additions and 0 deletions

BIN
TTOS/.DS_Store vendored Normal file

Binary file not shown.

232
TTOS/include/elf.h Normal file
View File

@@ -0,0 +1,232 @@
#ifndef _ELF_H
#define _ELF_H
#include <stdint.h>
#include "errorCode.h"
/* https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html */
/* ELF Data Types */
typedef uint32_t Elf32_Addr;
typedef uint32_t Elf32_Off;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Off;
typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
/* ELF Magic */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
/* Class */
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
/* Data encoding */
#define ELFDATANONE 0
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
/* Version */
#define EV_NONE 0
#define EV_CURRENT 1
/* Type */
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_LOOS 0xfe00
#define ET_HIOS 0xfeff
#define ET_LOPROC 0xff00
#define ET_HIPROC 0xffff
#define EI_NIDENT 16
typedef struct {
uint8_t e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
/* Program header types */
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7
#define PT_LOOS 0x60000000
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
typedef struct {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
/* Section header type */
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
#define SHT_LOOS 0x60000000
#define SHT_HIOS 0x6fffffff
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
/* Section header name index */
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
/* Section header flags */
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
#define SHF_MERGE 0x10
#define SHF_STRINGS 0x20
#define SHF_INFO_LINK 0x40
#define SHF_LINK_ORDER 0x80
#define SHF_OS_NONCONFORMING 0x100
#define SHF_GROUP 0x200
#define SHF_TLS 0x400
#define SHF_MASKOS 0x0ff00000
#define SHF_MASKPROC 0xf0000000
typedef struct {
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
} Elf64_Shdr;
/* Symbol table index values */
#define STN_UNDEF 0
typedef struct {
Elf64_Word st_name;
uint8_t st_info;
uint8_t st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
} Elf64_Sym;
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info;
} Elf64_Rel;
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info;
Elf64_Sxword r_addend;
} Elf64_Rela;
#define R_X86_64_NONE 0
#define R_X86_64_64 1
#define R_X86_64_PC32 2
#define R_X86_64_GOT32 3
#define R_X86_64_PLT32 4
#define R_X86_64_COPY 5
#define R_X86_64_GLOB_DAT 6
#define R_X86_64_JUMP_SLOT 7
#define R_X86_64_RELATIVE 8
#define R_X86_64_GOTPCREL 9
#define R_X86_64_32 10
#define R_X86_64_32S 11
#define R_X86_64_16 12
#define R_X86_64_PC16 13
#define R_X86_64_8 14
#define R_X86_64_PC8 15
#define R_X86_64_DPTMOD64 16
#define R_X86_64_DTPOFF64 17
#define R_X86_64_TPOFF64 18
#define R_X86_64_TLSGD 19
#define R_X86_64_TLSLD 20
#define R_X86_64_DTPOFF32 21
#define R_X86_64_GOTTPOFF 22
#define R_X86_64_TPOFF32 23
#define R_X86_64_PC64 24
#define R_X86_64_GOTOFF64 25
#define R_X86_64_GOTPC32 26
#define R_X86_64_SIZE32 32
#define R_X86_64_SIZE64 33
#define ELF64_R_SYM(i) ((i)>>32)
#define ELF64_R_TYPE(i) ((i)&0xffffffffL)
#define ELF64_R_INFO(s,t) (((s)<<32)+((t)&0xffffffffL))
typedef struct elf_file {
int size;
void* contents;
Elf64_Ehdr* ehdr;
Elf64_Phdr* phdr;
Elf64_Shdr* shdr;
} elf_file;
errorCode_t load_elf(const char* filename, elf_file* file);
errorCode_t get_elf_proc_size(elf_file* file, uint64_t* size);
errorCode_t populate_elf_proc(elf_file* file, void* tgt_addr);
errorCode_t find_symbol(elf_file* file, const char* name, uint64_t* offset);
errorCode_t free_elf(elf_file* file);
#endif

15
TTOS/include/errorCode.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _ERRORCODE_H
#define _ERRORCODE_H
typedef int errorCode_t;
#define IS_ERROR(n) (n < SUCCESS)
#define SUCCESS 0
#define EBADPARM -1
#define ENOTFOUND -2
#define EBADEXEC -3
#define EMEMORY -4
#define EFILESYS -5
#endif

22
TTOS/include/fs/fs.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef _FS_H
#define _FS_H
#include "errorCode.h"
/* fs_open flags */
#define O_RDONLY 00000000
#define O_WRONLY 00000001
#define O_RDWR 00000002
/* fs_seek whence */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
errorCode_t fs_open(const char* path, int flags, int* fd);
errorCode_t fs_write(int fd, const void *buf, int count, int* bytes_written);
errorCode_t fs_read(int fd, void *buf, int count, int* bytes_read);
errorCode_t fs_seek(int fd, int offset, int whence, int* distance);
errorCode_t fs_close(int fd);
#endif

15
TTOS/include/memory.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _MEMORY_H
#define _MEMORY_H
#include "errorCode.h"
#define PAGE_SIZE 4096
#define PAGE_ALIGN(n) (n + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)
errorCode_t allocate_user_memory(int size, void** addr);
errorCode_t free_user_memory(void* addr, int size);
errorCode_t get_kernel_memory(int size, void** addr);
errorCode_t free_kernel_memory(void* addr, int size);
#endif

19
TTOS/include/process.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _PROCESS_H
#define _PROCESS_H
#define STACK_SIZE 8192
#include "elf.h"
typedef struct process {
void* entry_point;
void* exec_start;
void* stack_start;
void* stack_end;
int size;
} process;
errorCode_t create_process(const char* file, process* proc);
errorCode_t free_process(process* proc);
#endif

6
TTOS/include/syscall.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _SYSCALL_H
#define _SYSCALL_H
long system_call(long n, ...);
#endif

5
TTOS/ld.script Normal file
View File

@@ -0,0 +1,5 @@
ENTRY(main)
SECTIONS
{
. = 0x000000; /* Image starts here */
}

16
TTOS/makefile Normal file
View File

@@ -0,0 +1,16 @@
CC=gcc
CFLAGS=-g -Wall -Iinclude
LFLAGS=
OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c)) $(patsubst %.c,%.o,$(wildcard src/fs/*.c))
all: ttos
ttos: $(OBJS)
$(CC) $(LFLAGS) -o ttos $(OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJS) ttos

307
TTOS/src/elf.c Normal file
View File

@@ -0,0 +1,307 @@
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "fs/fs.h"
#include "syscall.h"
#include "elf.h"
#include "process.h"
#include "memory.h"
static int validate_magic(uint8_t e_ident[EI_NIDENT]) {
// ELF Magic must match
if(e_ident[0] != ELFMAG0 || e_ident[1] != ELFMAG1 || e_ident[2] != ELFMAG2 || e_ident[3] != ELFMAG3) {
return -1;
}
// Currently, only support 64 bit executables
if(e_ident[4] != ELFCLASS64) {
return -1;
}
// Currently, only support LSB byte order executables
if(e_ident[5] != ELFDATA2LSB) {
return -1;
}
// Currently, only support ELF current version
if(e_ident[6] != EV_CURRENT) {
return -1;
}
return 0;
}
static errorCode_t get_file_data(const char* path, elf_file* file) {
int rc;
// Open the file
int fd = 0;
rc = fs_open(path, O_RDONLY, &fd);
if(IS_ERROR(rc)) {
return rc;
}
// Seek to the beginning and then the end
// to get the file size
fs_seek(fd, 0, SEEK_SET, 0);
rc = fs_seek(fd, 0, SEEK_END, &file->size);
if(IS_ERROR(file->size) || file->size == 0) {
return EBADEXEC;
}
rc = get_kernel_memory(file->size, &file->contents);
if(IS_ERROR(rc)) {
return rc;
}
// Seek to the beginning and read the file data
fs_seek(fd, 0, SEEK_SET, 0);
int bytes_read = 0;
rc = fs_read(fd, file->contents, file->size, &bytes_read);
// Check error if error use error code if one was returned
if(IS_ERROR(rc)) {
free_kernel_memory(file->contents, file->size);
fs_close(fd);
return rc;
}
// Check error ELIBBAD if data read != size
if(bytes_read != file->size) {
free_kernel_memory(file->contents, file->size);
fs_close(fd);
return EBADEXEC;
}
// Close the file and return
fs_close(fd);
return 0;
}
static Elf64_Phdr* get_program_header(elf_file* file, int index) {
return (Elf64_Phdr*)((char*)file->phdr + index * file->ehdr->e_phentsize);
}
static Elf64_Shdr* get_section_header(elf_file* file, int index) {
return (Elf64_Shdr*)((char*)file->shdr + index * file->ehdr->e_shentsize);
}
static void* find_external_symbol(elf_file* file, Elf64_Shdr *symtbl_shdr, Elf64_Word st_name) {
if(symtbl_shdr->sh_link == 0) {
return 0;
}
Elf64_Shdr* strtbl_hdr = get_section_header(file, symtbl_shdr->sh_link);
char* strtbl = (char*)((uint8_t*)file->contents + strtbl_hdr->sh_offset);
char* symbol_name = &(strtbl[st_name]);
if(strncmp(symbol_name, "system_call", 7) == 0) {
return system_call;
}
return 0;
}
static errorCode_t relocate_symbols(elf_file* file, void* tgt_addr) {
for(int i = 0; i < file->ehdr->e_shnum; i++) {
Elf64_Shdr* shdr = get_section_header(file, i);
if(shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
// Retrieve the sections headers for the relocation section, linked symbol table, and target section
Elf64_Shdr* rel_shdr = shdr;
Elf64_Shdr *symtbl_shdr = get_section_header(file, rel_shdr->sh_link);
Elf64_Shdr *tgt_shdr = get_section_header(file, rel_shdr->sh_info);
// Retrieve the linked symbol table
Elf64_Sym* symtbl = (Elf64_Sym*)((uint8_t*)file->contents + symtbl_shdr->sh_offset);
// Loop through each relocation entry and update the target
int entry_count = rel_shdr->sh_size / rel_shdr->sh_entsize;
for (int j = 0; j < entry_count; j++) {
Elf64_Rela* relhdr = (Elf64_Rela*)((uint8_t*)file->contents + rel_shdr->sh_offset + j*rel_shdr->sh_entsize);
Elf64_Xword symbol = ELF64_R_SYM(relhdr->r_info);
Elf64_Xword type = ELF64_R_TYPE(relhdr->r_info);
// Symbol address
// For relocatable files - start of the exec + offset to the section containing the symbol + offset to the symbol in the section (aka symbol value)
// For all other files - start of the exec + symbol value (aka virtual address)
// For undefined symbols - search for the symbol externally
void* symbol_address = 0;
if(file->ehdr->e_type == ET_REL) {
symbol_address = (void*)((uint8_t*)tgt_addr + file->shdr[symtbl[symbol].st_shndx].sh_offset + symtbl[symbol].st_value);
} else if(symtbl[symbol].st_shndx == STN_UNDEF) {
symbol_address = find_external_symbol(file, symtbl_shdr, symtbl[symbol].st_name);
} else {
symbol_address = (void*)((uint8_t*)tgt_addr + symtbl[symbol].st_value);
}
if(symbol_address == 0) {
return -1;
}
// Location in section to patch
// For relocatable files - start of exec + offset to patch section + offset in the section
// For all other files - start of the exec + relocation offset value (aka virtual address)
void* patch_location = file->ehdr->e_type == ET_REL ?
(void*)((uint8_t*)tgt_addr + tgt_shdr->sh_offset + relhdr->r_offset) :
(void*)((uint8_t*)tgt_addr + relhdr->r_offset);
// retrieve the addend, only applies to RELA entries
Elf64_Sxword addend = file->shdr[i].sh_type == SHT_RELA ? relhdr->r_addend : 0;
// https://refspecs.linuxbase.org/elf/x86_64-abi-0.98.pdf page 69
switch(type) {
case R_X86_64_PC8:
*(uint8_t*)patch_location = (uint8_t*)symbol_address + addend - (uint8_t*)patch_location;
break;
case R_X86_64_PC16:
*(uint16_t*)patch_location = (uint8_t*)symbol_address + addend - (uint8_t*)patch_location;
case R_X86_64_PC32:
case R_X86_64_PLT32:
*(uint32_t*)patch_location = (uint8_t*)symbol_address + addend - (uint8_t*)patch_location;
break;
case R_X86_64_PC64:
*(uint64_t*)patch_location = (uint8_t*)symbol_address + addend - (uint8_t*)patch_location;
break;
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
*(uint64_t*)patch_location = (uint64_t)symbol_address;
break;
}
// printf("%lX %lX %016lX %016lX\n", symbol, type, (uint64_t)symbol_address, (uint64_t)patch_location);
}
}
}
return SUCCESS;
}
errorCode_t load_elf(const char* path, elf_file* file) {
if(file == 0 || path == 0) {
return EBADPARM;
}
// Initialize the file and retrieve the file data
memset(file, 0x00, sizeof(elf_file));
int rc = get_file_data(path, file);
if(IS_ERROR(rc)) {
return rc;
}
// Validate the file magic value
if(validate_magic(file->contents) != 0) {
free_elf(file);
return EBADEXEC;
}
file->ehdr = (Elf64_Ehdr*)file->contents;
/* Only support dynamic linked files */
if(file->ehdr->e_type != ET_DYN) {
free_elf(file);
return EBADEXEC;
}
if(file->ehdr->e_phoff == 0) {
free_elf(file);
return EBADEXEC;
}
file->phdr = (Elf64_Phdr*)((uint8_t*)file->contents + file->ehdr->e_phoff);
if(file->ehdr->e_shoff == 0) {;
free_elf(file);
return EBADEXEC;
}
file->shdr = (Elf64_Shdr*)((uint8_t*)file->contents + file->ehdr->e_shoff);
return SUCCESS;
}
errorCode_t get_elf_proc_size(elf_file* file, uint64_t* size) {
if(file == 0 || size == 0) {
return EBADPARM;
}
// Determine the size to allocate for the process
// Determined by the highest address of any memory segment in the program header
Elf64_Phdr* highest_header = 0;
for(int i = 0; i < file->ehdr->e_phnum; i++) {
Elf64_Phdr *phdr = get_program_header(file, i);
if (phdr->p_type == PT_LOAD) {
if (highest_header == 0 || highest_header->p_vaddr < phdr->p_vaddr) {
highest_header = phdr;
}
}
}
*size = (uint64_t)highest_header->p_vaddr + (uint64_t)highest_header->p_memsz;
return SUCCESS;
}
errorCode_t populate_elf_proc(elf_file* file, void* tgt_addr) {
if(file == 0 || tgt_addr == 0) {
return EBADPARM;
}
// Copy program sections into the process
for(int i = 0; i < file->ehdr->e_shnum; i++) {
Elf64_Shdr* shdr = get_section_header(file, i);
if(shdr && (shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr > 0) {
memcpy(((uint8_t*)tgt_addr) + shdr->sh_addr, ((uint8_t*)file->contents) + shdr->sh_offset, shdr->sh_size);
}
}
// Relocate symbols
return relocate_symbols(file, tgt_addr);
}
errorCode_t find_symbol(elf_file* file, const char* name, uint64_t* offset) {
if(offset == 0) {
return EBADPARM;
}
// Search for a symbol
// Iterate through each section
for(int i = 0; i < file->ehdr->e_shnum; i++) {
// Find a section that represents a symbol table
Elf64_Shdr* shdr = get_section_header(file, i);
if(shdr->sh_type == SHT_SYMTAB) {
// Retrieve the corresponding string table
Elf64_Shdr* strtbl_hdr = get_section_header(file, shdr->sh_link);
char* strtbl = (char*)((uint8_t*)file->contents + strtbl_hdr->sh_offset);
// Iterate through each entry searching for the symbol string
int entry_count = shdr->sh_size / shdr->sh_entsize;
for(int j = 0; j < entry_count; j++) {
Elf64_Sym* symtbl = (Elf64_Sym*)((uint8_t*)file->contents + shdr->sh_offset + j*shdr->sh_entsize);
char* symbol_name = &(strtbl[symtbl->st_name]);
// Check symbol name and return offset
// For relocatable files - offset to symbol table + offset to the symbol (aka symbol value)
// For all other files - symbol value (aka virtual address)
if(strcmp(symbol_name, name) == 0) {
if(file->ehdr->e_type == ET_REL) {
*offset = file->shdr[symtbl->st_shndx].sh_offset + symtbl->st_value;
} else {
*offset = symtbl->st_value;
}
return SUCCESS;
}
}
}
}
return ENOTFOUND;
}
errorCode_t free_elf(elf_file* file) {
free_kernel_memory(file->contents, file->size);
memset(file, 0x00, sizeof(elf_file));
return SUCCESS;
}

57
TTOS/src/fs/fs.c Normal file
View File

@@ -0,0 +1,57 @@
#include <unistd.h>
#include <sys/syscall.h>
#include "errorCode.h"
errorCode_t fs_open(const char* path, int flags, int* fd) {
if(fd == 0) {
return EBADPARM;
}
int rc = syscall(SYS_open, path, flags);
if(rc == -1) {
return EFILESYS;
}
*fd = rc;
return SUCCESS;
}
errorCode_t fs_write(int fd, const void *buf, int count, int* bytes_written) {
int rc = syscall(SYS_write, fd, buf, count);
if(rc == -1) {
return EFILESYS;
}
if(bytes_written != 0) {
*bytes_written = rc;
}
return SUCCESS;
}
errorCode_t fs_read(int fd, void *buf, int count, int* bytes_read) {
int rc = syscall(SYS_read, fd, buf, count);
if(rc == -1) {
return EFILESYS;
}
if(bytes_read != 0) {
*bytes_read = rc;
}
return SUCCESS;
}
errorCode_t fs_seek(int fd, int offset, int whence, int* distance) {
int rc = syscall(SYS_lseek, fd, offset, whence);
if(rc == -1) {
return EFILESYS;
}
if(distance != 0) {
*distance = rc;
}
return SUCCESS;
}
errorCode_t fs_close(int fd) {
int rc = syscall(SYS_close, fd);
if(rc == -1) {
return EFILESYS;
}
return SUCCESS;
}

16
TTOS/src/main.c Normal file
View File

@@ -0,0 +1,16 @@
#include <stdio.h>
#include "process.h"
int main(int argc, char* argv[]) {
process out;
printf("%d\n", create_process("test", &out));
int (*main_exec)() = out.entry_point;
int ret_val = main_exec();
printf("%d\n", ret_val);
free_process(&out);
return 0;
}

52
TTOS/src/memory.c Normal file
View File

@@ -0,0 +1,52 @@
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include "errorCode.h"
#include "memory.h"
int allocate_user_memory(int size, void** addr) {
if(addr == 0) {
return EBADPARM;
}
uint64_t aligned_size = PAGE_ALIGN(size);
*addr = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(*addr == MAP_FAILED) {
*addr = 0;
return EMEMORY;
}
return SUCCESS;
}
int free_user_memory(void* addr, int size) {
if(addr == 0) {
return EBADPARM;
}
int rc = munmap(addr, size);
if(rc == -1) {
return EMEMORY;
}
return SUCCESS;
}
int get_kernel_memory(int size, void** addr) {
if(addr == 0) {
return EBADPARM;
}
*addr = malloc(size);
if(*addr == 0) {
return EMEMORY;
}
return SUCCESS;
}
int free_kernel_memory(void* addr, int size) {
if(addr == 0) {
return EBADPARM;
}
free(addr);
return SUCCESS;
}

80
TTOS/src/process.c Normal file
View File

@@ -0,0 +1,80 @@
#include <stdint.h>
#include <string.h>
#include "errorCode.h"
#include "elf.h"
#include "process.h"
#include "memory.h"
static errorCode_t allocate_process(int size, process* proc) {
int aligned_size = PAGE_ALIGN(size);
int rc = allocate_user_memory(aligned_size + STACK_SIZE, &(proc->exec_start));
if(IS_ERROR(rc)) {
return rc;
}
proc->stack_start = ((uint8_t*)(proc->exec_start) + aligned_size);
proc->stack_end = ((uint8_t*)(proc->stack_start) + STACK_SIZE);
proc->size = aligned_size + STACK_SIZE;
return SUCCESS;
}
int create_process(const char* path, process* proc) {
if(proc == 0) {
return EBADPARM;
}
// Load the executable file
elf_file file;
int rc = load_elf(path, &file);
if(IS_ERROR(rc)) {
return rc;
}
// Allocate the process address space
uint64_t proc_size = 0;
rc = get_elf_proc_size(&file, &proc_size);
if(IS_ERROR(rc)) {
free_elf(&file);
return rc;
}
memset(proc, 0x00, sizeof(process));
rc = allocate_process(proc_size, proc);
if(IS_ERROR(rc)) {
free_elf(&file);
return rc;
}
// Populate the process address space
rc = populate_elf_proc(&file, proc->exec_start);
if(IS_ERROR(rc)) {
free_elf(&file);
free_process(proc);
return rc;
}
// Set the process entry point
uint64_t offset_to_main = 0;
rc = find_symbol(&file, "main", &offset_to_main);
if(IS_ERROR(rc)) {
free_elf(&file);
free_process(proc);
return rc;
}
proc->entry_point = (void*)((uint8_t*)proc->exec_start + offset_to_main);
// Free the executable - no longer needed since process has been created
free_elf(&file);
return SUCCESS;
}
errorCode_t free_process(process* proc) {
if(proc == 0) {
return EBADPARM;
}
free_user_memory(proc->exec_start, proc->size);
proc->exec_start = 0;
proc->stack_start = 0;
proc->stack_end = 0;
proc->size = 0;
return SUCCESS;
}

21
TTOS/src/syscall.c Normal file
View File

@@ -0,0 +1,21 @@
#include <stdarg.h>
#include <stdio.h>
#include "fs/fs.h"
long system_call(long n, ...) {
long rc = 0;
va_list ap;
va_start(ap, n);
if(n == 1) {
int fd = va_arg(ap, int);
const char* buf = va_arg(ap, const char*);
int count = va_arg(ap, int);
int* bytes_written = va_arg(ap, int*);
rc = fs_write(fd, buf, count, bytes_written);
}
return rc;
}

27
TTOS/test.c Normal file
View File

@@ -0,0 +1,27 @@
//#include <stdio.h>
long system_call(long n, ...);
int j = 3;
int i = 10;
int foo3(int b);
int foo2(int b) {
return foo3(b) + 2;
}
int foo1(int a) {
return foo2(a) + 2 + i;
}
int main(int argc, char* argv[]) {
// printf("hi\n");
// j = 10;
system_call(1, 1, "abc\n", 4);
int result = foo1(5 + j);
system_call(1, 1, result, 4);
system_call(1, 1, "\n", 1);
return foo1(5 + j);
// return foo1(5 + j);
}

3
TTOS/test2.c Normal file
View File

@@ -0,0 +1,3 @@
int foo3(int b) {
return b + 3;
}