Compare commits

..

No commits in common. "master" and "merge_v" have entirely different histories.

26 changed files with 92 additions and 470 deletions

View File

@ -3,7 +3,7 @@ CPPFLAGS = -MMD
AS=nasm AS=nasm
ASFLAGS += -f elf32 ASFLAGS += -f elf32
LDFLAGS += -m elf_i386 LDFLAGS += -m elf_i386
CFLAGS += -m32 -pipe -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-pie -fno-stack-protector -fno-tree-vectorize -D__KERNEL__ CFLAGS += -m32 -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-pie -fno-stack-protector -fno-tree-vectorize -D__KERNEL__
#keep .i and .s #keep .i and .s
#CFLAGS += -save-temps #CFLAGS += -save-temps
#CFLAGS += -fanalyzer -Wno-analyzer-malloc-leak -Wno-analyzer-out-of-bounds #CFLAGS += -fanalyzer -Wno-analyzer-malloc-leak -Wno-analyzer-out-of-bounds
@ -88,16 +88,11 @@ test: clean kernel disk.img
run:kernel disk.img ## Run the OS on qemu run:kernel disk.img ## Run the OS on qemu
qemu-system-x86_64 -kernel $< -serial stdio $(QEMU_OPT) qemu-system-x86_64 -kernel $< -serial stdio $(QEMU_OPT)
debug: CFLAGS += $(DEBUG_FLAGS) ## Run the OS on qemu and attach a debugger to it (may need a clean before to have the debug symbols) debug: CFLAGS += $(DEBUG_FLAGS) ## Run the OS on qemu and attach a debugger to it (may need a clean befor to have the debug symbols)
debug: CXXFLAGS += $(DEBUG_FLAGS) debug: CXXFLAGS += $(DEBUG_FLAGS)
debug:kernel kernel.debug disk.img debug:kernel kernel.debug disk.img
gdb -q -x debug.gdb gdb -q -x debug.gdb
isodebug: CFLAGS += $(DEBUG_FLAGS) ## Same than previous but kernel is loaded by grub. So, for example, we can access the elf debug info
isodebug: CXXFLAGS += $(DEBUG_FLAGS)
isodebug:fd.iso disk.img
gdb -q -x debug.iso.gdb
debug_test: CFLAGS += $(DEBUG_FLAGS) -DRUN_TEST debug_test: CFLAGS += $(DEBUG_FLAGS) -DRUN_TEST
debug_test: debug debug_test: debug

View File

@ -53,12 +53,10 @@ void print_handler(struct cpu_state *frame, ulong intr)
void pagefault_handler(struct cpu_state *frame, ulong intr) void pagefault_handler(struct cpu_state *frame, ulong intr)
{ {
// PAGE_FAULT is a interrupt with an error code (see exception_wrapper.S)
uint32_t error_code = cpu_context_get_EX_err(frame);
struct thread *current = getCurrentThread();
struct thread *current = getCurrentThread();
assert(frame == current->cpuState);
if (cpu_context_is_in_user_mode(current->cpuState)) { if (cpu_context_is_in_user_mode(current->cpuState)) {
assert(frame == current->cpuState); // pagefault in kernel not supported ATM
struct uAddrSpace *as = processGetAddrSpace(current->process); struct uAddrSpace *as = processGetAddrSpace(current->process);
vaddr_t faultAddr = cpu_context_get_EX_faulting_vaddr(frame); vaddr_t faultAddr = cpu_context_get_EX_faulting_vaddr(frame);
@ -72,6 +70,8 @@ void pagefault_handler(struct cpu_state *frame, ulong intr)
if (!uAddrSpaceHeapCheckNAlloc(as, faultAddr)) if (!uAddrSpaceHeapCheckNAlloc(as, faultAddr))
goto release_context; goto release_context;
// PAGE_FAULT is a interrupt with an error code (see exception_wrapper.S)
uint32_t error_code = cpu_context_get_EX_err(frame);
int ret = uAddrSpaceSolvePageFault(as, faultAddr, error_code & 0x2); int ret = uAddrSpaceSolvePageFault(as, faultAddr, error_code & 0x2);
if (!ret) if (!ret)

View File

@ -138,17 +138,17 @@ uaddr_t loadElfProg(const char *prog, struct process *proc)
unrefPhyPage(ppage); unrefPhyPage(ppage);
} }
// Hack: Even if already allocated mark the adresse space as managed by a ressource
// So this address space is not used by another ressource.
uaddr = elf_phdrs[i].p_vaddr;
zeroMmap(as, &uaddr, elf_phdrs[i].p_memsz, PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ, 0);
/* Copy segment into memory */ /* Copy segment into memory */
memcpy((void *)elf_phdrs[i].p_vaddr, (void *)(prog + elf_phdrs[i].p_offset), memcpy((void *)elf_phdrs[i].p_vaddr, (void *)(prog + elf_phdrs[i].p_offset),
elf_phdrs[i].p_filesz); elf_phdrs[i].p_filesz);
if (lastUserAddr < uaddr) { if (lastUserAddr < uaddr) {
lastUserAddr = uaddr; lastUserAddr = uaddr;
} }
// Hack: Even if already allocated mark the adresse space as managed by a ressource
// So this address space is not used by another ressource.
uaddr = elf_phdrs[i].p_vaddr;
assert(zeroMmap(as, &uaddr, elf_phdrs[i].p_memsz, PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ, 0) == 0);
} }
processInitHeap(proc, lastUserAddr); processInitHeap(proc, lastUserAddr);

View File

@ -425,8 +425,7 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
case 'x': { case 'x': {
char val[sizeof(long long int) * 2]; char val[sizeof(long long int) * 2];
unsigned int valIdx = 0; unsigned int valIdx = 0;
unsigned long long int d = long long int d = va_arg(ap, long long int);
va_arg(ap, unsigned long long int);
itoa(d, val, 16); itoa(d, val, 16);
if (str) { if (str) {
while (val[valIdx]) { while (val[valIdx]) {
@ -454,7 +453,7 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
case 'x': { case 'x': {
char val[sizeof(int) * 2]; char val[sizeof(int) * 2];
unsigned int valIdx = 0; unsigned int valIdx = 0;
unsigned long int d = va_arg(ap, unsigned long int); long int d = va_arg(ap, long int);
itoa(d, val, 16); itoa(d, val, 16);
if (str) { if (str) {
while (val[valIdx]) { while (val[valIdx]) {

View File

@ -46,7 +46,7 @@ void idleThread(void *arg)
#define FILE_MAX_SIZE 64 // In nb of sectors #define FILE_MAX_SIZE 64 // In nb of sectors
void loadUserSpace() void loadUserSpace()
{ {
struct ata_partition *part = ATAGetPartitionByType(PART_TYPE_LINUX); struct ata_partition *part = ATAGetPartition(1);
if (part == NULL) { if (part == NULL) {
printf("No user partition found\n"); printf("No user partition found\n");

View File

@ -5,14 +5,12 @@
#include "list.h" #include "list.h"
#include "mmuContext.h" #include "mmuContext.h"
#include "types.h" #include "types.h"
#include "thread.h"
#include "uaddrspace.h" #include "uaddrspace.h"
struct process { struct process {
char name[PROCESS_NAME_MAX_LENGTH]; char name[PROCESS_NAME_MAX_LENGTH];
int ref; int ref;
pid_t pid; int pid;
pid_t nextTid;
struct uAddrSpace *addrSpace; struct uAddrSpace *addrSpace;
struct thread *thList; struct thread *thList;
@ -49,8 +47,7 @@ struct process *processCreate(char *name)
new->ref = 1; new->ref = 1;
disable_IRQs(flags); disable_IRQs(flags);
new->pid = nextPid++; new->pid = nextPid++;
new->nextTid = new->pid;
list_add_tail(processList, new); list_add_tail(processList, new);
restore_IRQs(flags); restore_IRQs(flags);
@ -69,7 +66,7 @@ void processListPrint()
struct thread *th; struct thread *th;
int nbTh; int nbTh;
printf("%lu %s %d %d\n", proc->pid, proc->name, processCountThread(proc), proc->ref); printf("%d %s %d %d\n", proc->pid, proc->name, processCountThread(proc), proc->ref);
list_foreach_named(proc->thList, th, nbTh, prevInProcess, nextInProcess) list_foreach_named(proc->thList, th, nbTh, prevInProcess, nextInProcess)
{ {
if (th == cur) { if (th == cur) {
@ -183,47 +180,3 @@ struct uAddrSpace *processGetAddrSpace(struct process *proc){
int processInitHeap(struct process *proc, uaddr_t lastUserAddr){ int processInitHeap(struct process *proc, uaddr_t lastUserAddr){
return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0); return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0);
} }
pid_t processGetId(struct process *proc){
return proc->pid;
}
pid_t processGetNextTid(struct process *proc){
return proc->nextTid++;
}
//Should be called with IRQ disabled
struct thread *processGetThread(struct process *proc, pid_t tid)
{
int count;
struct thread *th;
struct thread *thFound = NULL;
list_foreach_named(proc->thList, th, count, prevInProcess, nextInProcess)
{
if (th->tid == tid) {
thFound = th;
break;
}
}
return thFound;
}
int processJoinThread(struct process *proc, pid_t tid)
{
uint32_t flags;
struct thread *th;
int ret = -1;
disable_IRQs(flags);
th = processGetThread(proc, tid);
if (th && th->wqExit) {
wait(th->wqExit);
ret = 0;
}
restore_IRQs(flags);
return ret;
}

View File

@ -1,11 +1,9 @@
#pragma once #pragma once
#include "types.h" #include "thread.h"
#define PROCESS_NAME_MAX_LENGTH 32 #define PROCESS_NAME_MAX_LENGTH 32
typedef unsigned long int pid_t;
struct process; struct process;
struct thread;
int processSetup(); int processSetup();
struct process *processCreate(char *name); struct process *processCreate(char *name);
@ -20,6 +18,3 @@ int processRemoveThread(struct thread *th);
struct mmu_context *processGetMMUContext(struct process *th); struct mmu_context *processGetMMUContext(struct process *th);
struct uAddrSpace *processGetAddrSpace(struct process *proc); struct uAddrSpace *processGetAddrSpace(struct process *proc);
int processInitHeap(struct process *proc, uaddr_t lastUserAddr); int processInitHeap(struct process *proc, uaddr_t lastUserAddr);
pid_t processGetId(struct process *proc);
pid_t processGetNextTid(struct process *proc);
int processJoinThread(struct process *proc, pid_t tid);

View File

@ -1,8 +1,6 @@
#include "syscall.h" #include "syscall.h"
#include "kernel.h"
#include "keyboard.h" #include "keyboard.h"
#include "klibc.h" #include "klibc.h"
#include "paging.h"
#include "process.h" #include "process.h"
#include "stdarg.h" #include "stdarg.h"
#include "thread.h" #include "thread.h"
@ -11,6 +9,7 @@
#include "uaddrspace.h" #include "uaddrspace.h"
#include "zero.h" #include "zero.h"
int syscallExecute(int syscallId, const struct cpu_state *userCtx) int syscallExecute(int syscallId, const struct cpu_state *userCtx)
{ {
@ -44,17 +43,17 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5); printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5);
break; break;
} }
case SYSCALL_ID_BRK: { case SYSCALL_ID_BRK:{
struct uAddrSpace *as; struct uAddrSpace *as;
uaddr_t newHeapTop; uaddr_t newHeapTop;
as = processGetAddrSpace(getCurrentThread()->process); as = processGetAddrSpace(getCurrentThread()->process);
ret = syscallGet1arg(userCtx, (unsigned int *)&newHeapTop); ret = syscallGet1arg(userCtx, (unsigned int *)&newHeapTop);
if (ret != 0) if (ret != 0)
break; break;
threadChangeCurrentContext(uAddrSpaceGetMMUContext(as)); threadChangeCurrentContext(uAddrSpaceGetMMUContext(as));
// TODO : what if *newHeapTop raise page fault? //TODO : what if *newHeapTop raise page fault?
ret = sysBrk(as, newHeapTop); ret = sysBrk(as, newHeapTop);
threadChangeCurrentContext(NULL); threadChangeCurrentContext(NULL);
break; break;
@ -111,83 +110,6 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
ret = uAddrSpaceUnmap(as, uaddr, size); ret = uAddrSpaceUnmap(as, uaddr, size);
break; break;
} }
case SYSCALL_ID_NEW_THREAD: {
struct uAddrSpace *as;
thread_id_t threadIdPtr;
thread_id_t threadId;
uaddr_t funcAddr;
uint32_t arg1, arg2;
size_t stackSize;
ret = syscallGet5args(userCtx, (unsigned int *)&threadIdPtr,
(unsigned int *)&funcAddr, (unsigned int *)&arg1,
(unsigned int *)&arg2, (unsigned int *)&stackSize);
if (ret)
break;
if (stackSize <= 0) {
ret = -EINVAL;
break;
}
if (memcpyFromUser((vaddr_t)&threadId, threadIdPtr, sizeof(threadId)) !=
sizeof(threadId)) {
ret = -EFAULT;
break;
}
as = processGetAddrSpace(getCurrentThread()->process);
stackSize = ALIGN(stackSize, PAGE_SIZE);
uaddr_t stackAddr = 0;
ret = zeroMmap(as, &stackAddr, stackSize, PAGING_MEM_READ | PAGING_MEM_WRITE, 0);
if (ret)
break;
struct thread *th = threadCreateUser(NULL, getCurrentThread()->process, funcAddr,
arg1, arg2, stackAddr + stackSize);
if (th == NULL) {
ret = -ENOMEM;
uAddrSpaceUnmap(as, stackAddr, stackSize);
}
threadId = threadGetId(th);
if (memcpyToUser(threadIdPtr, (vaddr_t)&threadId, sizeof(threadId)) !=
sizeof(threadId)) {
ret = -EFAULT;
break;
}
break;
}
case SYSCALL_ID_USLEEP: {
unsigned int sleep;
ret = syscallGet1arg(userCtx, &sleep);
if (ret)
break;
ret = threadUsleep(sleep);
break;
}
case SYSCALL_ID_GETPID: {
ret = processGetId(getCurrentThread()->process);
break;
}
case SYSCALL_ID_GETTID: {
ret = threadGetId(getCurrentThread());
break;
}
case SYSCALL_ID_THREAD_JOIN: {
thread_id_t tid;
ret = syscallGet1arg(userCtx, (unsigned int *)&tid);
if (ret)
break;
ret = processJoinThread(getCurrentThread()->process, tid);
break;
}
default: default:
printf("Unknon syscall id %d\n", syscallId); printf("Unknon syscall id %d\n", syscallId);
ret = -ENOENT; ret = -ENOENT;

View File

@ -11,11 +11,6 @@
#define SYSCALL_ID_BRK 6 #define SYSCALL_ID_BRK 6
#define SYSCALL_ID_MMAP 7 #define SYSCALL_ID_MMAP 7
#define SYSCALL_ID_MUNMAP 8 #define SYSCALL_ID_MUNMAP 8
#define SYSCALL_ID_NEW_THREAD 9
#define SYSCALL_ID_USLEEP 10
#define SYSCALL_ID_GETPID 11
#define SYSCALL_ID_GETTID 12
#define SYSCALL_ID_THREAD_JOIN 13
#ifdef __KERNEL__ #ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx); int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -12,12 +12,6 @@
static struct thread *currentThread; static struct thread *currentThread;
static struct thread *threadWithTimeout; static struct thread *threadWithTimeout;
static thread_id_t nextTid; // This is the TID for kernel thread ONLY
pid_t threadGetId(struct thread *th)
{
return th->tid;
}
static void threadPrepareContext(struct thread *th); static void threadPrepareContext(struct thread *th);
@ -89,9 +83,7 @@ struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, v
(cpu_kstate_function_arg1_t *)threadExit, 0)) (cpu_kstate_function_arg1_t *)threadExit, 0))
goto free_mem; goto free_mem;
thread->state = READY; thread->state = READY;
thread->tid = nextTid++;
thread->wqExit = NULL;
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
list_add_tail(currentThread, thread); list_add_tail(currentThread, thread);
@ -118,14 +110,6 @@ struct thread *threadCreateUser(const char *name, struct process *proc, uaddr_t
} }
thread->stackSize = THREAD_DEFAULT_STACK_SIZE; thread->stackSize = THREAD_DEFAULT_STACK_SIZE;
thread->wqExit = (struct wait_queue * )malloc(sizeof(struct wait_queue));
if (!thread->wqExit) {
free((void *)thread->stackAddr);
free(thread);
return NULL;
}
waitQueueInit(thread->wqExit);
if (name) if (name)
strzcpy(thread->name, name, THREAD_NAME_MAX_LENGTH); strzcpy(thread->name, name, THREAD_NAME_MAX_LENGTH);
else else
@ -140,7 +124,6 @@ struct thread *threadCreateUser(const char *name, struct process *proc, uaddr_t
goto free_mem; goto free_mem;
thread->state = READY; thread->state = READY;
thread->tid = processGetNextTid(proc);
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
list_add_tail(currentThread, thread); list_add_tail(currentThread, thread);
@ -160,14 +143,9 @@ void threadDelete(struct thread *thread)
restore_IRQs(flags); restore_IRQs(flags);
assert(thread->state == EXITING); assert(thread->state == EXITING);
if (thread->wqExit) {
waitUp(thread->wqExit);
}
if (thread->squattedContext) { if (thread->squattedContext) {
mmuContextUnref(thread->squattedContext); threadChangeCurrentContext(NULL);
} }
if (thread->process) if (thread->process)
processRemoveThread(thread); processRemoveThread(thread);
@ -232,18 +210,17 @@ int threadOnJieffiesTick()
disable_IRQs(flags); disable_IRQs(flags);
list_foreach(currentThread, nextThread, idx) list_foreach(currentThread, nextThread, idx)
{ {
if (nextThread->state == SLEEPING) { if (nextThread->state == SLEEPING && nextThread->jiffiesSleeping) {
if (nextThread->jiffiesSleeping) nextThread->jiffiesSleeping--;
nextThread->jiffiesSleeping--; if (!nextThread->jiffiesSleeping) {
if (!nextThread->jiffiesSleeping)
nextThread->state = READY; nextThread->state = READY;
}
} }
} }
list_foreach_named(threadWithTimeout, nextThread, idx, timePrev, timeNext) list_foreach_named(threadWithTimeout, nextThread, idx, timePrev, timeNext)
{ {
if (nextThread->state == WAITING) { if (nextThread->state == WAITING && nextThread->jiffiesSleeping) {
if (nextThread->jiffiesSleeping) nextThread->jiffiesSleeping--;
nextThread->jiffiesSleeping--;
if (!nextThread->jiffiesSleeping) { if (!nextThread->jiffiesSleeping) {
nextThread->sleepHaveTimeouted = 1; nextThread->sleepHaveTimeouted = 1;
list_delete_named(threadWithTimeout, nextThread, timePrev, timeNext); list_delete_named(threadWithTimeout, nextThread, timePrev, timeNext);
@ -315,11 +292,6 @@ int threadYield()
} }
int threadMsleep(unsigned long msec) int threadMsleep(unsigned long msec)
{
return threadUsleep(msec*1000);
}
int threadUsleep(unsigned long usec)
{ {
uint32_t flags; uint32_t flags;
struct thread *next, *current; struct thread *next, *current;
@ -327,12 +299,12 @@ int threadUsleep(unsigned long usec)
disable_IRQs(flags); disable_IRQs(flags);
current = currentThread; current = currentThread;
assertmsg(current->state == RUNNING, "thread %s is in state %d for %lu us\n", current->name, assertmsg(current->state == RUNNING, "thread %s is in state %d for %lu\n", current->name,
current->state, usec); current->state, msec);
current->state = SLEEPING; current->state = SLEEPING;
current->sleepHaveTimeouted = 0; current->sleepHaveTimeouted = 0;
current->jiffiesSleeping = usecs_to_jiffies(usec); current->jiffiesSleeping = msecs_to_jiffies(msec);
next = threadSelectNext(); next = threadSelectNext();
assert(next != current); assert(next != current);

View File

@ -4,7 +4,6 @@ struct thread;
#include "cpu_context.h" #include "cpu_context.h"
#include "mem.h" #include "mem.h"
#include "process.h" #include "process.h"
#include "wait.h"
#define THREAD_NAME_MAX_LENGTH 32 #define THREAD_NAME_MAX_LENGTH 32
#define THREAD_DEFAULT_STACK_SIZE PAGE_SIZE #define THREAD_DEFAULT_STACK_SIZE PAGE_SIZE
@ -18,11 +17,8 @@ typedef enum {
EXITING EXITING
} thread_state; } thread_state;
typedef unsigned long int thread_id_t;
struct thread { struct thread {
char name[THREAD_NAME_MAX_LENGTH]; char name[THREAD_NAME_MAX_LENGTH];
thread_id_t tid;
struct cpu_state *cpuState; struct cpu_state *cpuState;
thread_state state; thread_state state;
vaddr_t stackAddr; vaddr_t stackAddr;
@ -36,7 +32,6 @@ struct thread {
// For User thread only // For User thread only
struct thread *nextInProcess, *prevInProcess; struct thread *nextInProcess, *prevInProcess;
struct process *process; struct process *process;
struct wait_queue *wqExit; // This will be signaled at thread exit (user only)
/** /**
* Address space currently "squatted" by the thread, or used to be * Address space currently "squatted" by the thread, or used to be
@ -88,10 +83,8 @@ int threadYield();
int threadWait(struct thread *current, struct thread *next, unsigned long msec); int threadWait(struct thread *current, struct thread *next, unsigned long msec);
int threadUnsched(struct thread *th); int threadUnsched(struct thread *th);
int threadMsleep(unsigned long msec); int threadMsleep(unsigned long msec);
int threadUsleep(unsigned long usec);
int threadOnJieffiesTick(); int threadOnJieffiesTick();
struct thread *getCurrentThread(); struct thread *getCurrentThread();
int threadAddThread(struct thread *th); int threadAddThread(struct thread *th);
int threadChangeCurrentContext(struct mmu_context *ctx); int threadChangeCurrentContext(struct mmu_context *ctx);
int threadCount(); int threadCount();
thread_id_t threadGetId(struct thread *th);

View File

@ -216,8 +216,7 @@ int uAddrSpaceUnmap(struct uAddrSpace *as, uaddr_t uaddr, size_t size)
reg->res->ops->unmap(reg, uaddr, size); reg->res->ops->unmap(reg, uaddr, size);
break; break;
// Only affect the end // Only affect the end
} else if (uaddr > reg->addr && uaddr < reg->addr + size && } else if (uaddr > reg->addr && uaddr + size > reg->addr + reg->size) {
uaddr + size > reg->addr + reg->size) {
size_t unmapSize = reg->addr + reg->size - uaddr; size_t unmapSize = reg->addr + reg->size - uaddr;
reg->size = uaddr - reg->addr; reg->size = uaddr - reg->addr;
@ -307,13 +306,7 @@ int uAddrSpaceHeapCheckNAlloc(struct uAddrSpace *as, vaddr_t addr)
newReg->size = PAGE_SIZE; newReg->size = PAGE_SIZE;
newReg->right = right; newReg->right = right;
// keep the AS list sorted list_add_tail_named(as->listVirtualReg, newReg, nextInAddrSpace, prevInAddrSpace);
struct uAddrVirtualReg *prev = findVirtualRegionBeforeAddr(as, addrAlign);
if (prev)
list_insert_after_named(as->listVirtualReg, prev, newReg, prevInAddrSpace,
nextInAddrSpace);
else
list_add_tail_named(as->listVirtualReg, newReg, nextInAddrSpace, prevInAddrSpace);
unrefPhyPage(ppage); unrefPhyPage(ppage);

View File

@ -1,9 +1,8 @@
#pragma once #pragma once
#include "mmuContext.h" #include "mmuContext.h"
#include "process.h" #include "process.h"
#include "stddef.h"
#include "stdint.h"
#include "types.h" #include "types.h"
#include <stddef.h>
struct uAddrSpace; struct uAddrSpace;
struct uAddrVirtualReg; struct uAddrVirtualReg;

View File

@ -1,10 +0,0 @@
add-symbol-file userspace/user
# Thx to add-gnu-debuglink gdb should know that symbols are in kernel.debug.
# And by default, it should be looking at executable.debug
# But we still have to give him the executable he is suppose to debug (See https://sourceware.org/gdb/current/onlinedocs/gdb.html/Separate-Debug-Files.html)
#add-symbol-file kernel.debug
file kernel
source custom_gdb_extension.py
#For ASM sources
directory arch/x86/:core
target remote | qemu-system-i386 -S -gdb stdio -m 16M -serial file:serialOut -hda fd.iso -hdb disk.img

View File

@ -521,19 +521,6 @@ struct ata_partition *ATAGetPartition(int id)
return NULL; return NULL;
} }
struct ata_partition *ATAGetPartitionByType(uint type)
{
struct ata_partition *part;
int count;
list_foreach(partitions, part, count)
{
if (part->type == type)
return part;
}
return NULL;
}
struct ata_partition *ATAPartitionCreate(uint type, uint size, uint32_t lba, struct ata_partition *ATAPartitionCreate(uint type, uint size, uint32_t lba,
struct ata_device *dev) struct ata_device *dev)
{ {

View File

@ -104,6 +104,5 @@ int ATAReadPartitionSector(struct ata_partition *part, int offset, uint nbSector
int ATAReadSector(struct ata_device *dev, int lba, uint nbSector, void *buf); int ATAReadSector(struct ata_device *dev, int lba, uint nbSector, void *buf);
int ATAWriteSector(struct ata_device *dev, int lba, uint nbSector, void *buf); int ATAWriteSector(struct ata_device *dev, int lba, uint nbSector, void *buf);
struct ata_device *ATAGetDevice(int ctlId, int devId); struct ata_device *ATAGetDevice(int ctlId, int devId);
struct ata_partition *ATAGetPartitionByType(uint type);
int ATAReadPartition(struct ata_device *dev); int ATAReadPartition(struct ata_device *dev);
struct ata_partition *ATAGetPartition(int id); struct ata_partition *ATAGetPartition(int id);

View File

@ -1,41 +1,13 @@
#include "zero.h" #include "zero.h"
#include "alloc.h" #include "alloc.h"
#include "errno.h"
#include "kernel.h" #include "kernel.h"
#include "klibc.h" #include "klibc.h"
#include "mem.h"
#include "list.h"
#include "paging.h"
#include "types.h"
struct zeroMappedPage {
uaddr_t mappedAddr;
paddr_t phyAddr;
struct zeroMappedPage *prev, *next;
};
struct zeroMappedEntry { struct zeroMappedEntry {
int refCnt; int refCnt;
struct zeroMappedPage *listMapped;
}; };
static int insertMappedPage(struct zeroMappedEntry *entry, uaddr_t vAddr, paddr_t pAddr){
struct zeroMappedPage *info = (struct zeroMappedPage *)zalloc(sizeof(struct zeroMappedPage));
if(!info)
return -ENOMEM;
info->mappedAddr = vAddr;
info->phyAddr = pAddr;
list_add_tail(entry->listMapped, info);
return 0;
}
static int zeroOpen(struct uAddrVirtualReg *vreg) static int zeroOpen(struct uAddrVirtualReg *vreg)
{ {
struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData; struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData;
@ -48,11 +20,6 @@ static int zeroClose(struct uAddrVirtualReg *vreg)
struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData; struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData;
ent->refCnt--; ent->refCnt--;
if (ent->refCnt == 0) { if (ent->refCnt == 0) {
struct zeroMappedPage *pageInfo;
list_collapse(ent->listMapped, pageInfo){
pageUnmap(pageInfo->mappedAddr);
free(pageInfo);
}
free(vreg->res->customData); free(vreg->res->customData);
free(vreg->res); free(vreg->res);
} }
@ -61,26 +28,17 @@ static int zeroClose(struct uAddrVirtualReg *vreg)
static int zeroNoPage(struct uAddrVirtualReg *vreg, uaddr_t addr, int right) static int zeroNoPage(struct uAddrVirtualReg *vreg, uaddr_t addr, int right)
{ {
int ret = 0; (void)vreg;
paddr_t ppage = allocPhyPage(1);
uaddr_t mappedAddr = ALIGN_DOWN(addr, PAGE_SIZE);
ret = pageMap(mappedAddr, ppage, right | PAGING_MEM_USER);
struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData; int ret = 0;
paddr_t ppage = allocPhyPage(1);
ret = pageMap(ALIGN_DOWN(addr, PAGE_SIZE), ppage, right | PAGING_MEM_USER) ;
unrefPhyPage(ppage); unrefPhyPage(ppage);
if (ret) { if (ret) {
return ret; return ret;
} }
memset((void *)ALIGN_DOWN(addr, PAGE_SIZE), 0, PAGE_SIZE);
ret = insertMappedPage(ent, mappedAddr, ppage);
if (ret) {
pageUnmap(mappedAddr);
return ret;
}
memset((void *)mappedAddr, 0, PAGE_SIZE);
return ret; return ret;
} }
@ -94,6 +52,9 @@ static struct mappedRessourceOps zeroOps = {
int zeroOnMapped(struct uAddrVirtualReg *vreg) int zeroOnMapped(struct uAddrVirtualReg *vreg)
{ {
(void)vreg; (void)vreg;
printf("ZERO MAPPED !!\n");
return 0; return 0;
} }
@ -106,8 +67,6 @@ int zeroMmap(struct uAddrSpace *as, uaddr_t *uaddr, size_t size, uint32_t rights
struct zeroMappedEntry *cust = struct zeroMappedEntry *cust =
(struct zeroMappedEntry *)zalloc(sizeof(struct zeroMappedEntry)); (struct zeroMappedEntry *)zalloc(sizeof(struct zeroMappedEntry));
list_init(cust->listMapped);
res->allowedRight = PAGING_MEM_READ | PAGING_MEM_WRITE | PAGING_MEM_EXEC | PAGING_MEM_USER; res->allowedRight = PAGING_MEM_READ | PAGING_MEM_WRITE | PAGING_MEM_EXEC | PAGING_MEM_USER;
res->ops = &zeroOps; res->ops = &zeroOps;
res->customData = cust; res->customData = cust;

View File

@ -306,8 +306,9 @@ void sleepThread(void *arg)
} }
unsigned long ellapsedTime = jiffies_to_msecs(jiffies - initialJiffies); unsigned long ellapsedTime = jiffies_to_msecs(jiffies - initialJiffies);
assertmsg(ellapsedTime >= 500 && ellapsedTime < 510, "ellapsedTime %lu\n", ellapsedTime); assertmsg(ellapsedTime >= 500 && ellapsedTime < 510, "ellapsedTime %lu\n", ellapsedTime);
threadMsleep(ULONG_MAX); threadMsleep(0);
assert(0); printf("I should never be showed\n");
assert(1);
} }
struct mutex mutexTest; struct mutex mutexTest;

View File

@ -11,11 +11,6 @@
#define SYSCALL_ID_BRK 6 #define SYSCALL_ID_BRK 6
#define SYSCALL_ID_MMAP 7 #define SYSCALL_ID_MMAP 7
#define SYSCALL_ID_MUNMAP 8 #define SYSCALL_ID_MUNMAP 8
#define SYSCALL_ID_NEW_THREAD 9
#define SYSCALL_ID_USLEEP 10
#define SYSCALL_ID_GETPID 11
#define SYSCALL_ID_GETTID 12
#define SYSCALL_ID_THREAD_JOIN 13
#ifdef __KERNEL__ #ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx); int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -5,8 +5,6 @@
#include "swintr.h" #include "swintr.h"
#include "sys/mman.h" #include "sys/mman.h"
#include "syscall.h" #include "syscall.h"
#include "thread.h"
#include "unistd.h"
int errno = 0; int errno = 0;
int memcmp(const void *aptr, const void *bptr, size_t size) int memcmp(const void *aptr, const void *bptr, size_t size)
@ -265,57 +263,8 @@ int puts(const char *str)
return ret; \ return ret; \
} }
#define PRINT_UINT(name, type) \
int print##name(type integer, char *str, size_t size) \
{ \
char num[sizeof(integer) * 3]; \
int i = 0; \
int c = 0; \
int ret = 0; \
\
do { \
int digit = integer % 10; \
num[i++] = (digit > 0) ? digit : -digit; \
integer = integer / 10; \
} while (integer != 0); \
\
for (i = i - 1; i >= 0; i--) { \
if (str) { \
if (size) { \
str[c++] = num[i] + '0'; \
size--; \
ret++; \
} else { \
return ret; \
} \
} else { \
ret++; \
} \
} \
return ret; \
}
PRINT_INT(Int, int); PRINT_INT(Int, int);
PRINT_INT(Lint, long int); PRINT_INT(Int64, long long int);
PRINT_INT(Llint, long long int);
PRINT_UINT(Uint, unsigned int);
PRINT_UINT(Luint, long unsigned int);
PRINT_UINT(Lluint, long long unsigned int);
#define PRINT_PART(func, type, str, size, c, ret) \
{ \
int s; \
type d = va_arg(ap, type); \
if (str) \
s = func(d, &str[c], size); \
else \
s = func(d, NULL, size); \
\
size -= s; \
c += s; \
ret += s; \
break; \
}
int vsnprintf(char *str, size_t size, const char *format, va_list ap) int vsnprintf(char *str, size_t size, const char *format, va_list ap)
{ {
@ -323,13 +272,24 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
int i = 0; int i = 0;
int c = 0; int c = 0;
while (format[i] != '\0' && (size|| !str)) { while (format[i] != '\0' && (size || !str)) {
switch (format[i]) { switch (format[i]) {
case '%': case '%':
switch (format[i + 1]) { switch (format[i + 1]) {
case 'i': case 'i':
case 'd': PRINT_PART(printInt, int, str, size, c, ret) case 'd': {
case 'u': PRINT_PART(printUint, uint, str, size, c, ret) int s;
int d = va_arg(ap, int);
if (str)
s = printInt(d, &str[c], size);
else
s = printInt(d, NULL, size);
size -= s;
c += s;
ret += s;
break;
}
case 'p': case 'p':
case 'x': { case 'x': {
char val[sizeof(int) * 2]; char val[sizeof(int) * 2];
@ -390,15 +350,24 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
switch (format[i + 2]) { switch (format[i + 2]) {
case 'l': case 'l':
switch (format[i + 3]) { switch (format[i + 3]) {
case 'i': case 'd': {
case 'd': PRINT_PART(printLlint, long long int, str, size, c, ret) int s;
case 'u': PRINT_PART(printLluint, long long unsigned int, str, size, c, ret) long long int d = va_arg(ap, long long int);
if (str)
s = printInt64(d, &str[c], size);
else
s = printInt64(d, NULL, size);
size -= s;
c += s;
ret += s;
break;
}
case 'p': case 'p':
case 'x': { case 'x': {
char val[sizeof(long long int) * 2]; char val[sizeof(long long int) * 2];
unsigned int valIdx = 0; unsigned int valIdx = 0;
unsigned long long int d = long long int d = va_arg(ap, long long int);
va_arg(ap, unsigned long long int);
itoa(d, val, 16); itoa(d, val, 16);
if (str) { if (str) {
while (val[valIdx]) { while (val[valIdx]) {
@ -419,28 +388,17 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
i++; i++;
break; break;
case 'i': case 'i':
case 'd': PRINT_PART(printLint, long int, str, size, c, ret) case 'd': {
case 'u': int s;
PRINT_PART(printLuint, long unsigned int, str, size, c, ret) long int d = va_arg(ap, long int);
case 'p': if (str)
case 'x': { s = printInt64(d, &str[c], size);
char val[sizeof(int) * 2]; else
unsigned int valIdx = 0; s = printInt64(d, NULL, size);
unsigned long int d = va_arg(ap, unsigned long int);
itoa(d, val, 16); size -= s;
if (str) { c += s;
while (val[valIdx]) { ret += s;
if (size) {
str[c++] = val[valIdx++];
size--;
ret++;
} else {
return ret;
}
}
} else {
ret += strlen(val);
}
break; break;
} }
} }
@ -787,40 +745,3 @@ int munmap(void *addr, size_t len)
return syscall2(SYSCALL_ID_MUNMAP, (unsigned int)addr, len); return syscall2(SYSCALL_ID_MUNMAP, (unsigned int)addr, len);
} }
/* As when a new thread is run, the params are passed by register (See cpu_ustate_init), use
* this function to simplify new thread usage*/
static void thread_runner()
{
register unsigned long int reg_arg1 asm("%eax");
register unsigned long int reg_arg2 asm("%ebx");
start_routine *func = (start_routine *)reg_arg1;
void *arg = (void *)reg_arg2;
func(arg);
_exit(0);
}
int thread_create(pthread_t *thread, start_routine *func, void *arg, size_t stackSize) {
return syscall5(SYSCALL_ID_NEW_THREAD, (unsigned int)thread, (unsigned int)thread_runner, (unsigned int)func,
(unsigned int)arg, stackSize);
}
int thread_join(pthread_t thread, void **retval){
(void)retval;
return syscall1(SYSCALL_ID_THREAD_JOIN, (unsigned int)thread);
}
int usleep(useconds_t usec) {
return syscall1(SYSCALL_ID_USLEEP, (unsigned int)usec);
}
pid_t gettid(void) {
return syscall0(SYSCALL_ID_GETTID);
}
pid_t getpid(void) {
return syscall0(SYSCALL_ID_GETPID);
}

View File

@ -4,7 +4,6 @@
#include "stdint.h" #include "stdint.h"
#include "stddef.h" #include "stddef.h"
#include "minmax.h" #include "minmax.h"
#include "unistd.h"
#define islower(c) (('a' <= (c)) && ((c) <= 'z')) #define islower(c) (('a' <= (c)) && ((c) <= 'z'))
#define isupper(c) (('A' <= (c)) && ((c) <= 'Z')) #define isupper(c) (('A' <= (c)) && ((c) <= 'Z'))
@ -64,6 +63,3 @@ void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size); void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size); void *realloc(void *ptr, size_t size);
void free(void *ptr); void free(void *ptr);
pid_t gettid(void);
pid_t getpid(void);

View File

@ -3,9 +3,7 @@
#include "stdarg.h" #include "stdarg.h"
#include "stddef.h" #include "stddef.h"
#include "sys/mman.h" #include "sys/mman.h"
#include "thread.h"
#include "tiny.h" #include "tiny.h"
#include "unistd.h"
int func_help() int func_help()
{ {
@ -17,7 +15,6 @@ int func_help()
printf(" tiny: a tiny C-like interpreter\n"); printf(" tiny: a tiny C-like interpreter\n");
printf(" mmap: test mmap \n"); printf(" mmap: test mmap \n");
printf(" munmap: test munmap \n"); printf(" munmap: test munmap \n");
printf(" thread: run a user thread\n");
return 0; return 0;
} }
@ -121,28 +118,11 @@ int func_munmap()
return ret; return ret;
} }
static void *print_hello(void *arg) { int main(int argc, char *argv[])
(void)arg; {
printf("Hello World from thread %lu\n", gettid());
usleep(100);
return NULL;
}
int func_thread() {
pthread_t id;
void *retval;
thread_create(&id, print_hello, NULL, 4096);
thread_join(id, &retval);
return 0;
}
int main(int argc, char *argv[]) {
(void)argc; (void)argc;
(void)argv; (void)argv;
char buf[64]; char buf[64];
assert(getpid() == gettid());
printf("Shell starting... type \"help\" for help\n"); printf("Shell starting... type \"help\" for help\n");
while (1) { while (1) {
printf(">"); printf(">");
@ -165,10 +145,7 @@ int main(int argc, char *argv[]) {
continue; continue;
} }
if (strcmp(buf, "tiny") == 0) { if (strcmp(buf, "tiny") == 0) {
pthread_t id; func_tiny();
void *retval;
thread_create(&id, func_tiny, NULL, 4096);
thread_join(id, &retval);
continue; continue;
} }
if (strcmp(buf, "mmap") == 0) { if (strcmp(buf, "mmap") == 0) {
@ -179,10 +156,6 @@ int main(int argc, char *argv[]) {
func_munmap(); func_munmap();
continue; continue;
} }
if (strcmp(buf, "thread") == 0) {
func_thread();
continue;
}
} }
return 0; return 0;
} }

View File

@ -1,8 +0,0 @@
#pragma once
#include <stddef.h>
typedef unsigned long int pthread_t;
typedef void *(start_routine)(void *);
int thread_create(pthread_t *thread, start_routine *func, void *arg, size_t stackSize);
/* retval is ignored ATM */
int thread_join(pthread_t thread, void **retval);

View File

@ -282,9 +282,8 @@ void run()
/* Main program. */ /* Main program. */
void * func_tiny(void *args) int func_tiny()
{ {
(void)args;
printf("Enter your program then ESC\n\n"); printf("Enter your program then ESC\n\n");
printf("TinyC grammar\n"); printf("TinyC grammar\n");
printf("<program> ::= <statement>\n"); printf("<program> ::= <statement>\n");

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
void * func_tiny(void *args); int func_tiny();

View File

@ -1,6 +0,0 @@
#pragma once
typedef unsigned int useconds_t;
int usleep(useconds_t usec);
typedef unsigned long int pid_t;