From 61582ad9f97f76574987172a0597a272253f9671 Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Mon, 30 Mar 2020 00:40:59 +0200 Subject: [PATCH] Physical memory refactor + update lib part + add arguments managements --- include/kernel/devices/earlyterm.h | 2 +- include/kernel/devices/tty.h | 4 +- include/kernel/drivers/keyboard.h | 2 +- include/kernel/fs/file.h | 14 +- include/kernel/fs/filesystem.h | 2 +- include/kernel/fs/gladfs.h | 2 +- include/kernel/fs/smemfs.h | 2 +- include/kernel/fs/vfs.h | 2 +- include/kernel/memory.h | 14 +- include/kernel/process.h | 6 +- include/kernel/syscall.h | 7 +- include/kernel/util/kmem.h | 13 ++ include/{kernel/util => lib/asm}/types.h | 0 include/{kernel/util => lib/asm}/unistd_32.h | 11 +- include/lib/errno.h | 156 ++++++++++++++++++ include/lib/fcntl.h | 20 +++ include/lib/stdlib.h | 30 ++++ include/lib/string.h | 3 + include/lib/sys/mman.h | 44 +++++ include/lib/unistd.h | 32 ++-- include/user/{ => shell}/builtin.h | 4 +- include/user/shell/util.h | 11 ++ include/user/util.h | 9 - src/kernel/Makefile | 2 +- src/kernel/bootstrap/mpu.c | 2 +- src/kernel/bootstrap/start.c | 2 +- src/kernel/devices/tty/operations/close.c | 8 +- src/kernel/devices/tty/operations/open.c | 18 +- src/kernel/devices/tty/operations/read.c | 8 +- .../fs/gladfs/superblock/alloc_fragdata.c | 4 +- src/kernel/fs/gladfs/superblock/alloc_inode.c | 4 +- .../fs/gladfs/superblock/destroy_fragdata.c | 4 +- .../fs/gladfs/superblock/destroy_inode.c | 4 +- src/kernel/fs/syscall/pread.c | 1 + src/kernel/fs/syscall/pwrite.c | 1 + src/kernel/fs/syscall/read.c | 1 + src/kernel/fs/syscall/write.c | 1 + src/kernel/fs/vfs/dentry/alloc.c | 4 +- src/kernel/fs/vfs/dentry/free.c | 4 +- src/kernel/fs/vfs/file/lseek.c | 1 + src/kernel/loader/entry.c | 1 + src/kernel/loader/reloc_sym.c | 7 +- src/kernel/memory/heap/alloc.c | 38 +---- src/kernel/memory/heap/block.c | 56 +++++++ src/kernel/memory/heap/debug.c | 3 +- src/kernel/memory/heap/free.c | 33 +--- src/kernel/memory/heap/realloc.c | 108 ++++++++++++ src/kernel/memory/initialize.c | 34 +++- .../memory/syscall/sys_proc_heap_alloc.c | 20 +++ .../memory/syscall/sys_proc_heap_free.c | 18 ++ .../memory/syscall/sys_proc_heap_realloc.c | 20 +++ src/kernel/scheduler/process/alloc.c | 4 +- src/kernel/scheduler/process/create.c | 11 +- src/kernel/scheduler/syscall/sys_fexecve.c | 43 ++++- src/kernel/syscall/handler.c | 7 +- src/kernel/util/kmem/alloc.c | 14 ++ src/kernel/util/kmem/debug.c | 12 ++ src/kernel/util/kmem/free.c | 12 ++ src/kernel/util/kmem/realloc.c | 25 +++ src/lib/Makefile | 2 +- src/lib/display/dascii.c | 3 +- src/lib/display/dclear.c | 2 +- src/lib/display/dopen.c | 2 +- src/lib/display/dreverse.c | 2 +- src/lib/display/dscroll.c | 2 +- src/lib/display/font_default5x3.c | 2 +- src/lib/libc/stdio/dprintf.c | 2 +- src/lib/libc/stdio/internal/printf_actions.c | 2 +- src/lib/libc/stdio/internal/printf_common.c | 2 +- src/lib/libc/stdio/internal/printf_options.c | 2 +- src/lib/libc/stdio/printf.c | 4 +- src/lib/libc/stdio/putc.c | 4 +- src/lib/libc/stdio/puts.c | 6 +- src/lib/libc/stdio/snprintf.c | 2 +- src/lib/libc/stdio/sprintf.c | 2 +- src/lib/libc/stdio/vdprintf.c | 4 +- src/lib/libc/stdio/vsnprintf.c | 2 +- src/lib/libc/stdio/vsprintf.c | 2 +- src/lib/libc/stdlib/calloc.c | 16 ++ src/lib/libc/stdlib/free.S | 17 ++ src/lib/libc/stdlib/malloc.S | 16 ++ src/lib/libc/stdlib/realloc.S | 46 ++++++ src/lib/libc/stdlib/reallocarray.c | 8 + src/lib/libc/string/memcpy.c | 3 +- src/lib/libc/string/memset.c | 2 +- src/lib/libc/string/strcat.c | 2 +- src/lib/libc/string/strchr.c | 2 +- src/lib/libc/string/strcmp.c | 2 +- src/lib/libc/string/strcpy.c | 2 +- src/lib/libc/string/strdup.c | 22 +++ src/lib/libc/string/strlen.c | 2 +- src/lib/libc/unistd/close.S | 2 +- src/lib/libc/unistd/fexecve.S | 2 +- src/lib/libc/unistd/getpgid.S | 2 +- src/lib/libc/unistd/getpid.S | 2 +- src/lib/libc/unistd/getppid.S | 2 +- src/lib/libc/unistd/lseek.S | 2 +- src/lib/libc/unistd/open.S | 2 +- src/lib/libc/unistd/read.S | 2 +- src/lib/libc/unistd/setpgid.S | 2 +- src/lib/libc/unistd/waitpid.S | 2 +- src/lib/libc/unistd/write.S | 2 +- src/user/shell/Makefile | 2 +- src/user/shell/builtin/fxdb.c | 3 +- src/user/shell/builtin/proc.c | 18 +- src/user/shell/main.c | 49 ++++-- src/user/shell/shell.ld | 6 - src/user/shell/util/check_builtin.c | 92 +---------- src/user/shell/util/strtotab.c | 15 +- src/user/test/Makefile | 2 +- src/user/test/test.c | 13 +- 111 files changed, 983 insertions(+), 353 deletions(-) create mode 100644 include/kernel/util/kmem.h rename include/{kernel/util => lib/asm}/types.h (100%) rename include/{kernel/util => lib/asm}/unistd_32.h (71%) create mode 100644 include/lib/errno.h create mode 100644 include/lib/fcntl.h create mode 100644 include/lib/stdlib.h create mode 100644 include/lib/sys/mman.h rename include/user/{ => shell}/builtin.h (91%) create mode 100644 include/user/shell/util.h delete mode 100644 include/user/util.h create mode 100644 src/kernel/memory/heap/block.c create mode 100644 src/kernel/memory/heap/realloc.c create mode 100644 src/kernel/memory/syscall/sys_proc_heap_alloc.c create mode 100644 src/kernel/memory/syscall/sys_proc_heap_free.c create mode 100644 src/kernel/memory/syscall/sys_proc_heap_realloc.c create mode 100644 src/kernel/util/kmem/alloc.c create mode 100644 src/kernel/util/kmem/debug.c create mode 100644 src/kernel/util/kmem/free.c create mode 100644 src/kernel/util/kmem/realloc.c create mode 100644 src/lib/libc/stdlib/calloc.c create mode 100644 src/lib/libc/stdlib/free.S create mode 100644 src/lib/libc/stdlib/malloc.S create mode 100644 src/lib/libc/stdlib/realloc.S create mode 100644 src/lib/libc/stdlib/reallocarray.c create mode 100644 src/lib/libc/string/strdup.c diff --git a/include/kernel/devices/earlyterm.h b/include/kernel/devices/earlyterm.h index 67fa39f..6e25a9e 100644 --- a/include/kernel/devices/earlyterm.h +++ b/include/kernel/devices/earlyterm.h @@ -3,7 +3,7 @@ #include #include -#include +#include // Wait for debug (dirty) // TODO: use earlyterm_read() to wait key event ? diff --git a/include/kernel/devices/tty.h b/include/kernel/devices/tty.h index f007010..634de6d 100644 --- a/include/kernel/devices/tty.h +++ b/include/kernel/devices/tty.h @@ -3,9 +3,9 @@ #include #include +#include #include -#include -#include +#include // Define default buffer size. // TODO: remove me ? diff --git a/include/kernel/drivers/keyboard.h b/include/kernel/drivers/keyboard.h index 28f0ff0..62e0b6b 100644 --- a/include/kernel/drivers/keyboard.h +++ b/include/kernel/drivers/keyboard.h @@ -3,7 +3,7 @@ #include #include -#include +#include #define KEYCODE_GEN(row, column) \ (((row & 0x0f) << 4) | ((column & 0x0f) << 0)) diff --git a/include/kernel/fs/file.h b/include/kernel/fs/file.h index 4fb9b4c..89fb522 100644 --- a/include/kernel/fs/file.h +++ b/include/kernel/fs/file.h @@ -3,24 +3,14 @@ #include #include -#include +#include #include #ifndef FILE_OPEN_NUMBER # define FILE_OPEN_NUMBER 4 #endif -// TODO: fix me -#ifndef __LIB_UNISTD_H__ -# define O_RDONLY 0x00 -# define O_WRONLY 0x01 -# define O_RDWR 0x02 - -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif - +// FILE type struct file_s { void *private; diff --git a/include/kernel/fs/filesystem.h b/include/kernel/fs/filesystem.h index 7523f57..d6f50ff 100644 --- a/include/kernel/fs/filesystem.h +++ b/include/kernel/fs/filesystem.h @@ -3,7 +3,7 @@ #include #include -#include +#include // FS flags #define FS_RDWR (0x01) diff --git a/include/kernel/fs/gladfs.h b/include/kernel/fs/gladfs.h index 6797363..b9e6862 100644 --- a/include/kernel/fs/gladfs.h +++ b/include/kernel/fs/gladfs.h @@ -3,7 +3,7 @@ #include #include -#include +#include # define GLADFS_INODE_NAME_LENGHT (16) diff --git a/include/kernel/fs/smemfs.h b/include/kernel/fs/smemfs.h index f67ba4d..b0e5f76 100644 --- a/include/kernel/fs/smemfs.h +++ b/include/kernel/fs/smemfs.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #define CASIO_SMEM_NAME_LENGHT 12 diff --git a/include/kernel/fs/vfs.h b/include/kernel/fs/vfs.h index b9bc66b..3245f90 100644 --- a/include/kernel/fs/vfs.h +++ b/include/kernel/fs/vfs.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/kernel/memory.h b/include/kernel/memory.h index eaa4eea..14af4f3 100644 --- a/include/kernel/memory.h +++ b/include/kernel/memory.h @@ -105,14 +105,20 @@ struct memory_info }; -// Function -extern void *pm_alloc(size_t size); -extern void pm_free(void *ptr); -extern void pm_debug(void); + +// "user" function +extern void *pm_heap_alloc(struct pm_heap_page **page, size_t size); +extern void *pm_heap_realloc(struct pm_heap_page **page, void *ptr, size_t size); +extern void pm_heap_debug(struct pm_heap_page *page); +extern void pm_heap_free(struct pm_heap_page *page, void *ptr); // Page allocator extern void *pm_pages_alloc(int nb_pages); extern void pm_pages_free(void *addr); +// Internal helpers +extern void *pm_block_split(struct pm_heap_block *block, size_t size); +extern void pm_block_frontmerge(struct pm_heap_block *block, void *brk); +extern void pm_block_backmerge(struct pm_heap_block **block, struct pm_heap_block *parent); #endif /*__KERNEL_MEMORY_H__*/ diff --git a/include/kernel/process.h b/include/kernel/process.h index bf0cec1..fcbac9d 100644 --- a/include/kernel/process.h +++ b/include/kernel/process.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #define PROCESS_NB_OPEN_FILE (4) #define PROCESS_USER_STACK_SIZE (2 * 1024) @@ -78,7 +78,7 @@ struct process void *start; size_t size; } exit; - struct heap *heap; + struct pm_heap_page *heap; } memory; @@ -120,7 +120,7 @@ extern struct process *process_create(void); extern int process_switch(pid_t pid); -// Internals +// Internals (kernel only) extern struct process *process_alloc(void); extern struct process *process_get(pid_t pid); extern int process_free(struct process *process); diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index 52e3da2..996ca94 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -3,7 +3,7 @@ #include #include -#include +#include // Process extern pid_t sys_getpid(void); @@ -12,7 +12,7 @@ extern pid_t sys_getpgid(void); extern pid_t sys_wait(int *wstatus); extern int sys_setpgid(pid_t pid, pid_t pgid); extern pid_t sys_waitpid(pid_t pid, int *wstatus, int options); -extern pid_t sys_fexecve(const char *pathname); +extern pid_t sys_fexecve(const char *pathname, char **argv, char **envp); extern void sys_exit(int status); // File @@ -28,5 +28,8 @@ extern int sys_close(int fd); extern void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); extern int sys_munmap(void *addr, size_t length); +extern void *sys_proc_heap_alloc(size_t size); +extern void *sys_proc_heap_realloc(void *ptr, size_t size); +extern void sys_proc_heap_free(void *ptr); #endif /*__SYSCALL_H__*/ diff --git a/include/kernel/util/kmem.h b/include/kernel/util/kmem.h new file mode 100644 index 0000000..67f9a6c --- /dev/null +++ b/include/kernel/util/kmem.h @@ -0,0 +1,13 @@ +#ifndef __KERNEL_UTIL_KMEM_H__ +# define __KERNEL_UTIL_KMEM_H__ + +#include +#include + +// Kernel memomries allocation function wrapper +extern void *kmem_alloc(size_t size); +extern void *kmem_realloc(void *ptr, size_t size); +extern void kmem_free(void *ptr); +extern void kmem_debug(void); + +#endif /*__KERNEL_UTIL_KMEM_H__*/ diff --git a/include/kernel/util/types.h b/include/lib/asm/types.h similarity index 100% rename from include/kernel/util/types.h rename to include/lib/asm/types.h diff --git a/include/kernel/util/unistd_32.h b/include/lib/asm/unistd_32.h similarity index 71% rename from include/kernel/util/unistd_32.h rename to include/lib/asm/unistd_32.h index 383ef1c..2cabdc3 100644 --- a/include/kernel/util/unistd_32.h +++ b/include/lib/asm/unistd_32.h @@ -1,8 +1,8 @@ -#ifndef __KERNEL_UNISTD_32_H__ -# define __KERNEL_UNISTD_32_H__ +#ifndef __ASM_UNISTD_32_H__ +# define __ASM_UNISTD_32_H__ // Define the number of syscall -#define __NR_MAX 18 +#define __NR_MAX 21 // Kernel Test #define __NR_test_syscall 0 @@ -29,5 +29,8 @@ // Memory #define __NR_mmap 16 #define __NR_munmap 17 +#define __NR_proc_heap_alloc 18 +#define __NR_proc_heap_free 19 +#define __NR_proc_heap_realloc 20 -#endif /*__KERNEL_UNISTD_32_H__*/ +#endif /*__ASM_UNISTD_32_H__*/ diff --git a/include/lib/errno.h b/include/lib/errno.h new file mode 100644 index 0000000..946131c --- /dev/null +++ b/include/lib/errno.h @@ -0,0 +1,156 @@ +#ifndef __KERNEL_ERRNO_H__ +# define __KERNEL_ERRNO_H__ 1 + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ + +/* + * This error code is special: arch syscall entry code will return + * -ENOSYS if users try to call a syscall that doesn't exist. To keep + * failures of syscalls that really do exist distinguishable from + * failures due to attempts to use a nonexistent syscall, syscall + * implementations should refrain from returning -ENOSYS. + */ +#define ENOSYS 38 /* Invalid system call number */ + +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define ENOTSUP EOPNOTSUPP /* Not supported (may be the same value as [EOPNOTSUPP]) */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ + +#define ERFKILL 132 /* Operation not possible due to RF-kill */ + +#define EHWPOISON 133 /* Memory page has hardware error */ + +#endif /* __KERNEL_ERRNO_H__ */ diff --git a/include/lib/fcntl.h b/include/lib/fcntl.h new file mode 100644 index 0000000..af54a7b --- /dev/null +++ b/include/lib/fcntl.h @@ -0,0 +1,20 @@ +#ifndef __LIB_FCNTL_H__ +# define __LIB_FCNTL_H__ + +#include +#include + +//TODO: update me !! +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +//TODO: define also in +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ + +// Functions +extern int open(const char *pathname, int flags, ...); + +#endif /*__LIB_FCNTL_H__*/ diff --git a/include/lib/stdlib.h b/include/lib/stdlib.h new file mode 100644 index 0000000..ab31228 --- /dev/null +++ b/include/lib/stdlib.h @@ -0,0 +1,30 @@ +#ifndef __LIB_STDLIB_H__ +# define __LIB_STDLIB_H__ + +#include +#include + + +#define HEAP_BLOCK_MIN (16) +struct heap_block +{ + uint16_t status; /* status of the block (1=used,0=free) */ + uint16_t size; /* size of the block (without block header) */ +} __attribute__((packed, aligned(2))); + +struct heap_page +{ + void *brk; /* break (address of the limit area) */ + size_t size; /* Page size (without header) */ + struct heap_page *next; /* Next heap page */ + struct heap_block heap; /* Start of block informations */ +} __attribute__((packed, aligned(4))); + +// Functions +extern void *malloc(size_t size); +extern void *calloc(size_t nmemb, size_t size); +extern void *realloc(void *ptr, size_t size); +extern void *reallocarray(void *ptr, size_t nmemb, size_t size); +extern void free(void *ptr); + +#endif /*__LIB_STDLIB_H__*/ diff --git a/include/lib/string.h b/include/lib/string.h index ffd15f0..6b1c087 100644 --- a/include/lib/string.h +++ b/include/lib/string.h @@ -26,4 +26,7 @@ extern size_t strlen(char const *str); /* strrchr() - find the last occurent of a byte */ extern char *strrchr(const char *s, int c); +/* strdup() - dump string */ +extern char *strdup(const char *s); + #endif /*__STRING_H__*/ diff --git a/include/lib/sys/mman.h b/include/lib/sys/mman.h new file mode 100644 index 0000000..7c3588c --- /dev/null +++ b/include/lib/sys/mman.h @@ -0,0 +1,44 @@ +#ifndef __LIB_SYS_MMAN_H__ +# define __LIB_SYS_MMAN_H__ + +#include +#include + +#ifndef __KERNEL_MEMORY_H__ +// mapping flags +// Protection (unused) +#define PROT_READ 0x1 /* Page can be read. */ +#define PROT_WRITE 0x2 /* Page can be written. */ +#define PROT_EXEC 0x4 /* Page can be executed. */ +#define PROT_NONE 0x0 /* Page can not be accessed. */ + +// Mapping flags +#define MAP_SHARED 0x01 /* Share changes. */ +#define MAP_PRIVATE 0x02 /* Changes are private. */ +#define MAP_ANONYMOUS 0x20 /* Don't use a file. */ +#define MAP_ANON MAP_ANONYMOUS /* Don't use a file. */ +#define MAP_FILE 0 /* Ignored. */ +#define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */ +#define MAP_DENYWRITE 0x00800 /* ETXTBSY. */ +#define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */ +#define MAP_LOCKED 0x02000 /* Lock the mapping. */ +#define MAP_NORESERVE 0x04000 /* Don't check for reservations. */ +#define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */ +#define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ +#define MAP_STACK 0x20000 /* Allocation is for a stack. */ +#define MAP_HUGETLB 0x40000 /* Create huge page mapping. */ +#define MAP_SYNC 0x80000 /* Perform synchronous page + faults for the mapping. */ +#define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED but do not unmap + underlying mapping. */ +#define MAP_UNINITIALIZED 0x200000 /* Don't clear anonymous page */ + +// Value returned when mmap value +#define MAP_FAILED ((void*) -1) +#endif + +// Prototype +extern void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); +extern int munmap(void *addr, size_t length); + +#endif /*__LIB_SYS_MMAN_H__*/ diff --git a/include/lib/unistd.h b/include/lib/unistd.h index 895d440..81c7bc8 100644 --- a/include/lib/unistd.h +++ b/include/lib/unistd.h @@ -3,16 +3,18 @@ #include #include -#include - -// Define syscall LIST -#include +#include // TODO: move me #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 +//TODO: move me +#define _SC_PAGE_SIZE 0 +#define _SC_PAGESIZE _SC_PAGE_SIZE + + //TODO: move me #define WNOHANG 0 #define WUNTRACED 1 @@ -23,31 +25,21 @@ #define __WEXITSTATUS(status) (((status) & 0xff00) >> 8) #define WEXITSTATUS(status) __WEXITSTATUS(status) +// Process part extern pid_t getpid(void); extern pid_t getpgid(void); extern pid_t getppid(void); extern int setpgid(pid_t pid, pid_t pgid); extern pid_t waitpid(pid_t pid, int *wstatus, int options); -extern pid_t fexecve(const char *pathname); +extern pid_t fexecve(const char *pathname, char **argv, char **envp); -// File syscall -// TODO: move me -// FIXME: find real value -#ifndef __FILE_H__ -# define O_DIRECT 0 -# define O_DIRECTORY 1 -# define O_RDONLY 2 -# define O_WRONLY 4 -# define O_RDWR 8 - -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif -extern int open(const char *pathname, int flags, ...); +// File part extern ssize_t write(int fd, const void *buf, size_t count); extern ssize_t read(int fd, void *buf, size_t count); extern off_t lseek(int fd, off_t offset, int whence); extern int close(int fd); +// System part +extern long sysconf(int name); + #endif /*__LIB_UNISTD_H__*/ diff --git a/include/user/builtin.h b/include/user/shell/builtin.h similarity index 91% rename from include/user/builtin.h rename to include/user/shell/builtin.h index 1a1fb37..c4a0f95 100644 --- a/include/user/builtin.h +++ b/include/user/shell/builtin.h @@ -8,7 +8,7 @@ // Generate a "command block" stored in ".cmd.cahce" section. // We need to "hide" the block, so we generate anonyme name using // __COUNTER__ macros. -#define gen_name(n) _##n +/*#define gen_name(n) _##n #define anonym_name(n) gen_name(n) #define VHEX_BUILTIN(builtin) \ static int builtin(int argc, char **argv); \ @@ -18,6 +18,7 @@ .entry = builtin \ }; \ static int builtin(int argc, char **argv) +*/ // Define builtin struct. struct builtin_s @@ -29,6 +30,7 @@ struct builtin_s // Builtin list extern int builtin_proc(void); extern int builtin_ram(void); +extern int builtin_fxdb(int argc, char **argv); #endif /*__USER_BUILTIN_H__*/ diff --git a/include/user/shell/util.h b/include/user/shell/util.h new file mode 100644 index 0000000..a61491f --- /dev/null +++ b/include/user/shell/util.h @@ -0,0 +1,11 @@ +#ifndef __USER_UTIL_H__ +# define __USER_UTIL_H__ + +#include +#include + +extern int check_builtin(int argc, char **argv); +extern int strtotab(int *argc, char ***argv, char const *str); +extern void strtotab_quit(int *argc, char ***argv); + +#endif /*__USER_UTIL_H__*/ diff --git a/include/user/util.h b/include/user/util.h deleted file mode 100644 index ef5a9c7..0000000 --- a/include/user/util.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __USER_UTIL_H__ -# define __USER_UTIL_H__ - -#include -#include - -extern int check_builtin(char *cmd); - -#endif /*__USER_UTIL_H__*/ diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 1298851..b92a0dc 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -11,7 +11,7 @@ include ../../global.mk ##--- ## Static variables ##-- -HEADER := -I../../include +HEADER := -I../../include -I../../include/lib BUILD := ../../build/kernel OUTPUT := ../../output DEBUG := ../../debug_bin diff --git a/src/kernel/bootstrap/mpu.c b/src/kernel/bootstrap/mpu.c index d9ccfbf..52a82a2 100644 --- a/src/kernel/bootstrap/mpu.c +++ b/src/kernel/bootstrap/mpu.c @@ -1,4 +1,4 @@ -#include +#include /* check_sh3 - Detecting sh3-based MPU */ static mpu_t check_sh3(uint16_t tplcr) diff --git a/src/kernel/bootstrap/start.c b/src/kernel/bootstrap/start.c index 57d77d2..ce1c487 100644 --- a/src/kernel/bootstrap/start.c +++ b/src/kernel/bootstrap/start.c @@ -1,7 +1,7 @@ #include #include // Internal helpers -#include +#include #include #include // Modules diff --git a/src/kernel/devices/tty/operations/close.c b/src/kernel/devices/tty/operations/close.c index 9f88522..b63e358 100644 --- a/src/kernel/devices/tty/operations/close.c +++ b/src/kernel/devices/tty/operations/close.c @@ -1,5 +1,5 @@ #include -#include +#include int tty_close(void *inode) { @@ -13,10 +13,10 @@ int tty_close(void *inode) // output buffer line = tty->cursor.max.y; while (line >= 0) - pm_free(tty->buffers.output[line]); - pm_free(tty->buffers.output); + kmem_free(tty->buffers.output[line]); + kmem_free(tty->buffers.output); // Free'd tty object - pm_free(tty); + kmem_free(tty); return (0); } diff --git a/src/kernel/devices/tty/operations/open.c b/src/kernel/devices/tty/operations/open.c index 365ea09..1c8e73e 100644 --- a/src/kernel/devices/tty/operations/open.c +++ b/src/kernel/devices/tty/operations/open.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include @@ -15,14 +15,14 @@ void *tty_open(dev_t major, dev_t minor) (void)minor; // Try to allocate tty object - tty = (struct tty_s*)pm_alloc(sizeof(struct tty_s)); + tty = (struct tty_s*)kmem_alloc(sizeof(struct tty_s)); if (tty == NULL) return (NULL); // Get the font used by the tty. if (dopen(&tty->disp, "default") != 0) { - pm_free(tty); + kmem_free(tty); return (NULL); } @@ -38,10 +38,10 @@ void *tty_open(dev_t major, dev_t minor) tty->cursor.max.y = tty->cursor.max.y * 4; // Try to alloc new tty output buffer - tty->buffers.output = (char **)pm_alloc(sizeof(char *) * tty->cursor.max.y); + tty->buffers.output = (char **)kmem_alloc(sizeof(char *) * tty->cursor.max.y); if (tty->buffers.output == NULL) { - pm_free(tty); + kmem_free(tty); return (NULL); } @@ -50,16 +50,16 @@ void *tty_open(dev_t major, dev_t minor) while (--line >= 0) { // Try to alloc the line - tty->buffers.output[line] = (char*)pm_alloc(tty->cursor.max.x); + tty->buffers.output[line] = (char*)kmem_alloc(tty->cursor.max.x); if (tty->buffers.output[line] != NULL) { memset(tty->buffers.output[line], '\0', tty->cursor.max.x); continue; } // Release all allocated space and return NULL while (++line < tty->cursor.max.y) - pm_free(tty->buffers.output[line]); - pm_free(tty->buffers.output); - pm_free(tty); + kmem_free(tty->buffers.output[line]); + kmem_free(tty->buffers.output); + kmem_free(tty); return (NULL); } diff --git a/src/kernel/devices/tty/operations/read.c b/src/kernel/devices/tty/operations/read.c index 59a0c63..2cbe5e2 100644 --- a/src/kernel/devices/tty/operations/read.c +++ b/src/kernel/devices/tty/operations/read.c @@ -119,7 +119,13 @@ static int check_special(struct keyboard_obj_s *keyboard, key_t key) return (1); } - // Check DEL key. + // Check space key + if (key == KEY_DOT && (keyboard->mode & 1) == 0) { + buffer_insert(keyboard, ' '); + return (1); + } + + // Check DEL key. if (key == KEY_DEL) { // Check potential error. diff --git a/src/kernel/fs/gladfs/superblock/alloc_fragdata.c b/src/kernel/fs/gladfs/superblock/alloc_fragdata.c index f953665..87afd1c 100644 --- a/src/kernel/fs/gladfs/superblock/alloc_fragdata.c +++ b/src/kernel/fs/gladfs/superblock/alloc_fragdata.c @@ -1,5 +1,5 @@ #include -#include +#include #include /* gladfs_alloc_fragdata() - Superblock primitive to alloc "empty" fragment data block (sync) */ @@ -15,7 +15,7 @@ int gladfs_alloc_fragdata(struct gladfs_fragment_data_s **parent, int nb_block) atomic_start(); // Try to alloc block - *parent = pm_alloc(gladfs_superblock.block_size * nb_block); + *parent = kmem_alloc(gladfs_superblock.block_size * nb_block); if (*parent == NULL) { atomic_stop(); diff --git a/src/kernel/fs/gladfs/superblock/alloc_inode.c b/src/kernel/fs/gladfs/superblock/alloc_inode.c index 5a2565a..9c578e7 100644 --- a/src/kernel/fs/gladfs/superblock/alloc_inode.c +++ b/src/kernel/fs/gladfs/superblock/alloc_inode.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -12,7 +12,7 @@ struct gladfs_inode_s *gladfs_alloc_inode(const char *name, mode_t mode) atomic_start(); // alloc memory - inode = pm_alloc(sizeof(struct gladfs_inode_s)); + inode = kmem_alloc(sizeof(struct gladfs_inode_s)); if (inode == NULL) { atomic_stop(); diff --git a/src/kernel/fs/gladfs/superblock/destroy_fragdata.c b/src/kernel/fs/gladfs/superblock/destroy_fragdata.c index 2497548..68ca0d7 100644 --- a/src/kernel/fs/gladfs/superblock/destroy_fragdata.c +++ b/src/kernel/fs/gladfs/superblock/destroy_fragdata.c @@ -1,5 +1,5 @@ #include -#include +#include #include /* gladfs_destroy_fragdata() - Free'd allocated fragmented data (sync) */ @@ -14,7 +14,7 @@ int gladfs_destroy_fragdata(struct gladfs_fragment_data_s *fragment) atomic_start(); // Free'd allocated space - pm_free(fragment); + kmem_free(fragment); // Stop atomic operation atomic_stop(); diff --git a/src/kernel/fs/gladfs/superblock/destroy_inode.c b/src/kernel/fs/gladfs/superblock/destroy_inode.c index 0d74745..4e4f8ed 100644 --- a/src/kernel/fs/gladfs/superblock/destroy_inode.c +++ b/src/kernel/fs/gladfs/superblock/destroy_inode.c @@ -1,5 +1,5 @@ #include -#include +#include #include /* gladfs_destroy_inode() - Free'd allocated inode (sync) */ @@ -29,7 +29,7 @@ int gladfs_destroy_inode(struct gladfs_inode_s *inode) } // Free inode - pm_free(inode); + kmem_free(inode); // Stop atomic operations atomic_stop(); diff --git a/src/kernel/fs/syscall/pread.c b/src/kernel/fs/syscall/pread.c index 5d5e2ed..924a657 100644 --- a/src/kernel/fs/syscall/pread.c +++ b/src/kernel/fs/syscall/pread.c @@ -1,5 +1,6 @@ #include #include +#include ssize_t sys_pread(int fd, void *buf, size_t count, off_t offset) { diff --git a/src/kernel/fs/syscall/pwrite.c b/src/kernel/fs/syscall/pwrite.c index be6b841..f4c8908 100644 --- a/src/kernel/fs/syscall/pwrite.c +++ b/src/kernel/fs/syscall/pwrite.c @@ -1,5 +1,6 @@ #include #include +#include ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t offset) { diff --git a/src/kernel/fs/syscall/read.c b/src/kernel/fs/syscall/read.c index 3dba265..f451464 100644 --- a/src/kernel/fs/syscall/read.c +++ b/src/kernel/fs/syscall/read.c @@ -1,5 +1,6 @@ #include #include +#include ssize_t sys_read(int fd, void *buf, size_t count) { diff --git a/src/kernel/fs/syscall/write.c b/src/kernel/fs/syscall/write.c index be86d4e..e1a3bf7 100644 --- a/src/kernel/fs/syscall/write.c +++ b/src/kernel/fs/syscall/write.c @@ -1,5 +1,6 @@ #include #include +#include ssize_t sys_write(int fd, const void *buf, size_t count) { diff --git a/src/kernel/fs/vfs/dentry/alloc.c b/src/kernel/fs/vfs/dentry/alloc.c index 3a01f2e..ff09031 100644 --- a/src/kernel/fs/vfs/dentry/alloc.c +++ b/src/kernel/fs/vfs/dentry/alloc.c @@ -1,5 +1,5 @@ #include -#include +#include #include /* vfs_dentry_alloc() - Allocate new "empty" dentry */ @@ -8,7 +8,7 @@ struct dentry *vfs_dentry_alloc(const char *name, mode_t mode) struct dentry *node; // Try to create new dentry - node = pm_alloc(sizeof(struct dentry)); + node = kmem_alloc(sizeof(struct dentry)); if (node == NULL) return (NULL); diff --git a/src/kernel/fs/vfs/dentry/free.c b/src/kernel/fs/vfs/dentry/free.c index 0132541..1b95c53 100644 --- a/src/kernel/fs/vfs/dentry/free.c +++ b/src/kernel/fs/vfs/dentry/free.c @@ -1,5 +1,5 @@ #include -#include +#include /* vfs_dentry_free() - Free'd allocated dentry */ /* @note: *WARNING* no verification will be done, so do not use this primitive */ @@ -10,5 +10,5 @@ void vfs_dentry_free(struct dentry *dentry) return; // Free'd allocated space - pm_free(dentry); + kmem_free(dentry); } diff --git a/src/kernel/fs/vfs/file/lseek.c b/src/kernel/fs/vfs/file/lseek.c index e05818c..f28b1ac 100644 --- a/src/kernel/fs/vfs/file/lseek.c +++ b/src/kernel/fs/vfs/file/lseek.c @@ -1,5 +1,6 @@ #include #include +#include /* vfs_lseek() - File cursor management */ off_t vfs_lseek(FILE *file, off_t offset, int whence) diff --git a/src/kernel/loader/entry.c b/src/kernel/loader/entry.c index 7caf463..a79059e 100644 --- a/src/kernel/loader/entry.c +++ b/src/kernel/loader/entry.c @@ -3,6 +3,7 @@ #include #include #include +#include // // TODO: write doc diff --git a/src/kernel/loader/reloc_sym.c b/src/kernel/loader/reloc_sym.c index 585df11..60c247f 100644 --- a/src/kernel/loader/reloc_sym.c +++ b/src/kernel/loader/reloc_sym.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -19,7 +20,7 @@ static char *get_shstrtab(FILE *file, Elf32_Ehdr *header) // Allocate dump area earlyterm_write("Try to alloc strtab (%do)\n", shdr.sh_size); - shstrtab = (char*)pm_alloc(shdr.sh_size); + shstrtab = (char*)kmem_alloc(shdr.sh_size); if (shstrtab == NULL) { earlyterm_write("relo_sym:mem (%d)\n", shdr.sh_size); @@ -30,7 +31,7 @@ static char *get_shstrtab(FILE *file, Elf32_Ehdr *header) if (vfs_pread(file, shstrtab, shdr.sh_size, shdr.sh_offset) != (ssize_t)shdr.sh_size) { earlyterm_write("relo_sym: shstrtab size error\n"); - pm_free(shstrtab); + kmem_free(shstrtab); return (NULL); } return (shstrtab); @@ -102,6 +103,6 @@ int loader_reloc_sym(struct process *process, FILE *file, Elf32_Ehdr *header) if (reloc_section(process, file, &shdr) != 0) return (-3); } - pm_free(shstrtab); + kmem_free(shstrtab); return (0); } diff --git a/src/kernel/memory/heap/alloc.c b/src/kernel/memory/heap/alloc.c index f00774a..98dc875 100644 --- a/src/kernel/memory/heap/alloc.c +++ b/src/kernel/memory/heap/alloc.c @@ -2,35 +2,6 @@ #include #include -static void *pm_block_split(struct pm_heap_block *block, size_t size) -{ - size_t rest_size; - void *ret; - - // Check size - if (block->size < size) - return (NULL); - - // Change current block status - block->status = 1; - - // Check if we can not split - rest_size = block->size - (size + sizeof(struct pm_heap_block)); - if (rest_size < PM_HEAP_BLOCK_MIN) - return (&block[1]); - - // Update current block size and get the - // returned value - block->size = size; - ret = &block[1]; - - // Initialize seconde block - block = (void *)&block[1] + block->size; - block->status = 0; - block->size = rest_size; - return (ret); -} - static void *new_pages(struct pm_heap_page **page, size_t size) { int nb_page; @@ -57,7 +28,7 @@ static void *new_pages(struct pm_heap_page **page, size_t size) return (pm_block_split(&(*page)->heap, size)); } -static void *pm_heap_alloc(struct pm_heap_page *page, size_t size) +static void *pm_heap_page_check(struct pm_heap_page *page, size_t size) { struct pm_heap_block *block; size_t rest_size; @@ -85,10 +56,8 @@ static void *pm_heap_alloc(struct pm_heap_page *page, size_t size) } // Kernel malloc wrapper -void *pm_alloc(size_t size) +void *pm_heap_alloc(struct pm_heap_page **page, size_t size) { - extern struct memory_info pmemory; - struct pm_heap_page **page; void *ret; // Force 4-align @@ -98,7 +67,6 @@ void *pm_alloc(size_t size) atomic_start(); // Walk into each pages x_x - page = &pmemory.kheap; while (*page != NULL) { // Check "page" size @@ -108,7 +76,7 @@ void *pm_alloc(size_t size) } // Try to find free space in the page - ret = pm_heap_alloc(*page, size); + ret = pm_heap_page_check(*page, size); if (ret != NULL) { atomic_stop(); return (ret); diff --git a/src/kernel/memory/heap/block.c b/src/kernel/memory/heap/block.c new file mode 100644 index 0000000..727ff7f --- /dev/null +++ b/src/kernel/memory/heap/block.c @@ -0,0 +1,56 @@ +#include + +void *pm_block_split(struct pm_heap_block *block, size_t size) +{ + int rest_size; + void *ret; + + // Check size + if (block->size < size) + return (NULL); + + // Change current block status + block->status = 1; + + // Check if we can not split + rest_size = block->size - (size + sizeof(struct pm_heap_block)); + if (rest_size < PM_HEAP_BLOCK_MIN) + return (&block[1]); + + // Update current block size and get the + // returned value + block->size = size; + ret = &block[1]; + + // Initialize seconde block + block = (void *)&block[1] + block->size; + block->status = 0; + block->size = rest_size; + return (ret); +} + +void pm_block_backmerge(struct pm_heap_block **block, struct pm_heap_block *parent) +{ + // Check back-merge possibility + if (parent == NULL || parent->status != 0) + return; + + // Absorb current block + parent->size += (*block)->size + sizeof(struct pm_heap_block); + + // Switch current block + *block = parent; +} + +void pm_block_frontmerge(struct pm_heap_block *block, void *brk) +{ + struct pm_heap_block *block_front; + + // Check front-merge possibility + block_front = (void*)&block[1] + block->size; + if ((void*)block_front >= brk || block_front->status != 0) + return; + + // Absorb front block + block->size += block_front->size + sizeof(struct pm_heap_block); +} diff --git a/src/kernel/memory/heap/debug.c b/src/kernel/memory/heap/debug.c index 1ccc2b3..df519a6 100644 --- a/src/kernel/memory/heap/debug.c +++ b/src/kernel/memory/heap/debug.c @@ -1,11 +1,10 @@ #include #include -void pm_debug(void) +void pm_heap_debug(struct pm_heap_page *page) { extern struct memory_info pmemory; struct pm_heap_block *block; - struct pm_heap_page *page; page = pmemory.kheap; while (page != NULL) diff --git a/src/kernel/memory/heap/free.c b/src/kernel/memory/heap/free.c index edaad7c..cad5fae 100644 --- a/src/kernel/memory/heap/free.c +++ b/src/kernel/memory/heap/free.c @@ -2,33 +2,6 @@ #include #include -static void pm_block_backmerge(struct pm_heap_block **block, - struct pm_heap_block *parent) -{ - // Check back-merge possibility - if (parent == NULL || parent->status != 0) - return; - - // Absorb current block - parent->size += (*block)->size + sizeof(struct pm_heap_block); - - // Switch current block - *block = parent; -} - -static void pm_block_frontmerge(struct pm_heap_block *block, void *brk) -{ - struct pm_heap_block *block_front; - - // Check front-merge possibility - block_front = (void*)&block[1] + block->size; - if ((void*)block_front >= brk || block_front->status != 0) - return; - - // Absorb front block - block->size += block_front->size + sizeof(struct pm_heap_block); -} - static int pm_block_free(struct pm_heap_page *page, void *ptr) { struct pm_heap_block *block_parent; @@ -57,16 +30,12 @@ static int pm_block_free(struct pm_heap_page *page, void *ptr) return (-1); } -void pm_free(void *ptr) +void pm_heap_free(struct pm_heap_page *page, void *ptr) { - extern struct memory_info pmemory; - struct pm_heap_page *page; - // Start atomic operations atomic_start(); // Try to find the page - page = pmemory.kheap; while (page != NULL) { // If is the page is found diff --git a/src/kernel/memory/heap/realloc.c b/src/kernel/memory/heap/realloc.c new file mode 100644 index 0000000..beb103e --- /dev/null +++ b/src/kernel/memory/heap/realloc.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +// Internal function +extern void *pm_block_split(struct pm_heap_block *block, size_t size); +extern void pm_block_backmerge(struct pm_heap_block **block, struct pm_heap_block *parent); +extern void pm_block_frontmerge(struct pm_heap_block *block, void *brk); + +static int pm_block_update(struct pm_heap_block *block, size_t size, void *brk) +{ + struct pm_heap_block *block_front; + + // Check front block validity + block_front = (void*)&block[1] + block->size; + if ((void*)block_front >= brk || block_front->status != 0) + return (-1); + + // Check size + if (block_front->size + sizeof(struct pm_heap_block) + block->size < size) + return (-1); + + // merge front block and try to split the block + block->size += block_front->size + sizeof(struct pm_heap_block); + pm_block_split(block, size); + return (0); +} + +static void *pm_block_realloc(struct pm_heap_page **page, void *ptr, size_t size) +{ + struct pm_heap_block *block_parent; + struct pm_heap_block *block; + struct pm_heap_block *new; + + block_parent = NULL; + block = &(*page)->heap; + while ((void*)block < (*page)->brk) + { + // check block validity + if ((void*)&block[1] != ptr) + { + block_parent = block; + block = (void*)&block[1] + block->size; + continue; + } + + // Check useless action + if (block->size >= size || pm_block_update(block, size, (*page)->brk) == 0) + return (&block[1]); + + // Manually alloc new node + new = pm_heap_alloc(page, size); + if (new == NULL) + return (&block[1]); + + // Copie old place + memcpy(new, &block[1], block->size); + + // Try back-merge / front merge current block + pm_block_backmerge(&block, block_parent); + pm_block_frontmerge(block, (*page)->brk); + + // Update block status + block->status = 0; + return (new); + } + return (NULL); +} + +void *pm_heap_realloc(struct pm_heap_page **page, void *ptr, size_t size) +{ + void *ret; + + // Force 4-align + size = (size + 3) >> 2 << 2; + + // Start atomic operations + atomic_start(); + + // Try to find the page + while (page != NULL) + { + // If is the page is found + if (ptr > (void*)page && ptr < (*page)->brk) + { + // Check if the block is not found + ret = pm_block_realloc(page, ptr, size); + + // Stop atomic operations and return area + atomic_stop(); + return (ret); + } + // Get the next page + page = &(*page)->next; + } + + // No block found, display error. + earlyterm_write( + "pm_free: Warning, you try to realloc" + "unused or allocated memory (%p)", ptr + ); + DBG_WAIT; + + // Stop atomic operations + atomic_stop(); + return (NULL); +} diff --git a/src/kernel/memory/initialize.c b/src/kernel/memory/initialize.c index 0dce692..aeffe80 100644 --- a/src/kernel/memory/initialize.c +++ b/src/kernel/memory/initialize.c @@ -1,5 +1,6 @@ #include #include +#include // Internal data. struct memory_info pmemory; @@ -49,19 +50,34 @@ void memory_init(void) } // TEST part -/* void *test0 = pm_alloc(16); - void *test1 = pm_alloc(128); - void *test2 = pm_alloc(80); +/* void *test0 = kmem_alloc(16); + void *test1 = kmem_alloc(128); + void *test2 = kmem_alloc(80); earlyterm_write("test0 = %p\n", test0); earlyterm_write("test1 = %p\n", test1); earlyterm_write("test2 = %p\n", test2); - pm_free(test2); - pm_free(test0); - pm_heap_debug(); + kmem_free(test1); + //kmem_debug(); + //DBG_WAIT; + test1 = kmem_realloc(NULL, 16); + //earlyterm_write("test1 = %p\n", test1); + //kmem_debug(); + //DBG_WAIT; + test1 = kmem_realloc(test1, 32); + earlyterm_write("test1 = %p\n", test1); + kmem_debug(); DBG_WAIT; - pm_free(test1); - pm_debug(); - pm_free((void*)0xa0000000); + //test1 = kmem_realloc(test1, 10); + //earlyterm_write("test1 = %p\n", test1); + //kmem_debug(); + //DBG_WAIT; + test1 = kmem_realloc(test1, 128); + earlyterm_write("test1 = %p\n", test1); + kmem_debug(); + DBG_WAIT; + test1 = kmem_realloc(test1, 200); + earlyterm_write("test1 = %p\n", test1); + kmem_debug(); DBG_WAIT; while (1);*/ } diff --git a/src/kernel/memory/syscall/sys_proc_heap_alloc.c b/src/kernel/memory/syscall/sys_proc_heap_alloc.c new file mode 100644 index 0000000..0e61f8c --- /dev/null +++ b/src/kernel/memory/syscall/sys_proc_heap_alloc.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +void *sys_proc_heap_alloc(size_t size) +{ + extern struct process *process_current; + void *ret; + + // start atomic operations + atomic_start(); + + // Try to alloc new uninitialized area + ret = pm_heap_alloc(&process_current->memory.heap, size); + + // Stop atomic operation + atomic_stop(); + return (ret); +} diff --git a/src/kernel/memory/syscall/sys_proc_heap_free.c b/src/kernel/memory/syscall/sys_proc_heap_free.c new file mode 100644 index 0000000..80652ee --- /dev/null +++ b/src/kernel/memory/syscall/sys_proc_heap_free.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +void sys_proc_heap_free(void *ptr) +{ + extern struct process *process_current; + + // start atomic operations + atomic_start(); + + // Freed allocated area + pm_heap_free(process_current->memory.heap, ptr); + + // Stop atomic operation + atomic_stop(); +} diff --git a/src/kernel/memory/syscall/sys_proc_heap_realloc.c b/src/kernel/memory/syscall/sys_proc_heap_realloc.c new file mode 100644 index 0000000..edeb86b --- /dev/null +++ b/src/kernel/memory/syscall/sys_proc_heap_realloc.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +void *sys_proc_heap_realloc(void *ptr, size_t size) +{ + extern struct process *process_current; + void *ret; + + // start atomic operations + atomic_start(); + + // Try to alloc new uninitialized area + ret = pm_heap_realloc(&process_current->memory.heap, ptr, size); + + // Stop atomic operation + atomic_stop(); + return (ret); +} diff --git a/src/kernel/scheduler/process/alloc.c b/src/kernel/scheduler/process/alloc.c index 630d80f..c909db6 100644 --- a/src/kernel/scheduler/process/alloc.c +++ b/src/kernel/scheduler/process/alloc.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include // TODO: return EAGAIN !! // TODO: return ENOMEM !! @@ -42,7 +42,7 @@ struct process *process_alloc(void) } // Alloc new process manually - *proc = (struct process *)pm_alloc(sizeof(struct process)); + *proc = (struct process *)kmem_alloc(sizeof(struct process)); if (*proc == NULL) { earlyterm_write("proc_alloc: ENOMEM !\n"); atomic_stop(); diff --git a/src/kernel/scheduler/process/create.c b/src/kernel/scheduler/process/create.c index 9b9c71a..680ed43 100644 --- a/src/kernel/scheduler/process/create.c +++ b/src/kernel/scheduler/process/create.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -38,7 +38,7 @@ struct process *process_create(void) { earlyterm_write("proc_error: kernel stack error !"); DBG_WAIT; - pm_free((void *)process->memory.stack.user); + pm_pages_free((void *)process->memory.stack.user); process_free(process); return (NULL); } @@ -56,8 +56,8 @@ struct process *process_create(void) process->memory.exit.start = pm_pages_alloc(PM_SIZE_TO_PAGES(process->memory.exit.size)); if (process->memory.exit.start == NULL) { - pm_free(process->memory.stack.user); - pm_free(process->memory.stack.kernel); + pm_pages_free(process->memory.stack.user); + pm_pages_free(process->memory.stack.kernel); process_free(process); return (NULL); } @@ -88,6 +88,9 @@ struct process *process_create(void) process->working_dir = vfs_root_node; process->tty.private = NULL; + // Initialize heap + process->memory.heap = NULL; + // DEBUG ! //earlyterm_write("proc_create: success !\n"); //earlyterm_write("* user stack: %p\n", process->context.reg[15]); diff --git a/src/kernel/scheduler/syscall/sys_fexecve.c b/src/kernel/scheduler/syscall/sys_fexecve.c index 85341e7..c919058 100644 --- a/src/kernel/scheduler/syscall/sys_fexecve.c +++ b/src/kernel/scheduler/syscall/sys_fexecve.c @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include //TODO //TODO COPY-ON-WRITE !! @@ -21,15 +22,43 @@ static void proc_dump_shared(struct process *child, struct process *parent) memcpy(&child->tty, &parent->tty, sizeof(FILE)); } +static int generate_arguments(struct process *proc, char **argv, char **envp) +{ + // Generate argc + proc->context.reg[4] = -1; + while (argv[++proc->context.reg[4]] != NULL); + + // Generate process argv area + proc->context.reg[5] = (uint32_t)pm_heap_alloc(&proc->memory.heap, sizeof(char*) * proc->context.reg[4]); + if (proc->context.reg[5] == 0x00000000) + return (-1); + + // Dump argv + for (uint32_t i = 0 ; i < proc->context.reg[4] ; ++i) + { + ((char**)proc->context.reg[5])[i] = pm_heap_alloc(&proc->memory.heap, strlen(argv[i])); + strcpy(((char**)proc->context.reg[5])[i], argv[i]); + } + + //TODO: envp + (void)envp; + return (0); +} + //TODO //TODO Return EAGAIN if no proc can be created !! //TODO Return ENOMEM if no memories can be allocated !! //TODO -pid_t sys_fexecve(const char *pathname) +pid_t sys_fexecve(const char *pathname, char **argv, char **envp) { extern struct process *process_current; struct process *proc; + // CHeck error + // TODO: set errno to EFAULT + if (argv == NULL) + return (-1); + // Start atomic operation atomic_start(); @@ -57,6 +86,16 @@ pid_t sys_fexecve(const char *pathname) return (-1); } + // Generate arguments + if (generate_arguments(proc, argv, envp) != 0) + { + earlyterm_write("sys_fexecve: arguements error\n"); + DBG_WAIT; + process_free(proc); + atomic_stop(); + return (-1); + } + // Release child process proc->sibling = process_current->child; process_current->child = proc; diff --git a/src/kernel/syscall/handler.c b/src/kernel/syscall/handler.c index 999b811..3af6487 100644 --- a/src/kernel/syscall/handler.c +++ b/src/kernel/syscall/handler.c @@ -1,6 +1,6 @@ #include -#include #include +#include static void sys_test(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { @@ -38,7 +38,10 @@ static const void *sys_handler[__NR_MAX] = { // Memory sys_mmap, // mmap - NULL//sys_munmap // munmap + NULL, // munmap + sys_proc_heap_alloc, // (custom) process heap alloc + sys_proc_heap_free, // (custom) process heap free + sys_proc_heap_realloc // (custom) process heap realloc }; void *sys_get_handler(int sysno) diff --git a/src/kernel/util/kmem/alloc.c b/src/kernel/util/kmem/alloc.c new file mode 100644 index 0000000..9ae67f9 --- /dev/null +++ b/src/kernel/util/kmem/alloc.c @@ -0,0 +1,14 @@ +#include +#include +#include + +void *kmem_alloc(size_t size) +{ + extern struct memory_info pmemory; + void *ret; + + atomic_start(); + ret = pm_heap_alloc(&pmemory.kheap, size); + atomic_stop(); + return (ret); +} diff --git a/src/kernel/util/kmem/debug.c b/src/kernel/util/kmem/debug.c new file mode 100644 index 0000000..22e530c --- /dev/null +++ b/src/kernel/util/kmem/debug.c @@ -0,0 +1,12 @@ +#include +#include +#include + +void kmem_debug(void) +{ + extern struct memory_info pmemory; + + atomic_start(); + pm_heap_debug(pmemory.kheap); + atomic_stop(); +} diff --git a/src/kernel/util/kmem/free.c b/src/kernel/util/kmem/free.c new file mode 100644 index 0000000..2d814c8 --- /dev/null +++ b/src/kernel/util/kmem/free.c @@ -0,0 +1,12 @@ +#include +#include +#include + +void kmem_free(void *ptr) +{ + extern struct memory_info pmemory; + + atomic_start(); + pm_heap_free(pmemory.kheap, ptr); + atomic_stop(); +} diff --git a/src/kernel/util/kmem/realloc.c b/src/kernel/util/kmem/realloc.c new file mode 100644 index 0000000..bc9b858 --- /dev/null +++ b/src/kernel/util/kmem/realloc.c @@ -0,0 +1,25 @@ +#include +#include +#include + +void *kmem_realloc(void *ptr, size_t size) +{ + extern struct memory_info pmemory; + void *ret; + + // Check malloc + if (ptr == NULL) + return (kmem_alloc(size)); + + // Check free + if (size == 0) { + kmem_free(ptr); + return (0); + } + + // Call common realloc part. + atomic_start(); + ret = pm_heap_realloc(&pmemory.kheap, ptr, size); + atomic_stop(); + return (ret); +} diff --git a/src/lib/Makefile b/src/lib/Makefile index 414517c..faefc9e 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -11,7 +11,7 @@ include ../../global.mk #------- --------# # Generic variables # #------- --------# -HEADER := -I../../include +HEADER := -I../../include/lib BUILD-STATIC := ../../build/lib/static BUILD-DYNAMIC := ../../build/lib/dynamic TARGET-MODULES := libc display diff --git a/src/lib/display/dascii.c b/src/lib/display/dascii.c index e9bec92..8b4b3c6 100644 --- a/src/lib/display/dascii.c +++ b/src/lib/display/dascii.c @@ -1,5 +1,4 @@ -#include -#include +#include static void font_draw_core(uint32_t *vram, struct font_s *font, struct font_block_s *fblock) { diff --git a/src/lib/display/dclear.c b/src/lib/display/dclear.c index 773b124..f3aec6a 100644 --- a/src/lib/display/dclear.c +++ b/src/lib/display/dclear.c @@ -1,4 +1,4 @@ -#include +#include /* dclear() - Wipe the Video RAM */ void dclear(display_t *disp) diff --git a/src/lib/display/dopen.c b/src/lib/display/dopen.c index cbb98ab..110b1d3 100644 --- a/src/lib/display/dopen.c +++ b/src/lib/display/dopen.c @@ -1,4 +1,4 @@ -#include +#include int dopen(display_t *disp, const char *fontname) { diff --git a/src/lib/display/dreverse.c b/src/lib/display/dreverse.c index 233ab05..0280c01 100644 --- a/src/lib/display/dreverse.c +++ b/src/lib/display/dreverse.c @@ -1,4 +1,4 @@ -#include +#include /* dreverse() - Reverse Video RAM area */ void dreverse(display_t *disp, int x, int y, int width, int height) diff --git a/src/lib/display/dscroll.c b/src/lib/display/dscroll.c index 4d3d5c5..c01c9c5 100644 --- a/src/lib/display/dscroll.c +++ b/src/lib/display/dscroll.c @@ -1,4 +1,4 @@ -#include +#include /* dscroll() - Scroll up the Video RAM */ //FIXME: This part is hardware specific (128x64px)!! diff --git a/src/lib/display/font_default5x3.c b/src/lib/display/font_default5x3.c index 1f12eb7..36f5bc3 100644 --- a/src/lib/display/font_default5x3.c +++ b/src/lib/display/font_default5x3.c @@ -1,4 +1,4 @@ -#include +#include // Define the (hardcoded) font bitmap informations. #define DEFAULT_FONT_BITMAP_WIDTH (127) // Bitmap width diff --git a/src/lib/libc/stdio/dprintf.c b/src/lib/libc/stdio/dprintf.c index 1b12e49..f001ff3 100644 --- a/src/lib/libc/stdio/dprintf.c +++ b/src/lib/libc/stdio/dprintf.c @@ -1,4 +1,4 @@ -#include +#include int dprintf(int fd, const char *restrict format, ...) { diff --git a/src/lib/libc/stdio/internal/printf_actions.c b/src/lib/libc/stdio/internal/printf_actions.c index 8d959ae..2c12379 100644 --- a/src/lib/libc/stdio/internal/printf_actions.c +++ b/src/lib/libc/stdio/internal/printf_actions.c @@ -1,4 +1,4 @@ -#include +#include // Define all actions static void action_str(struct printf_opt *op, char n); diff --git a/src/lib/libc/stdio/internal/printf_common.c b/src/lib/libc/stdio/internal/printf_common.c index 5be23fa..9f74655 100644 --- a/src/lib/libc/stdio/internal/printf_common.c +++ b/src/lib/libc/stdio/internal/printf_common.c @@ -1,4 +1,4 @@ -#include +#include //TODO: precision handling int printf_common(struct printf_opt *opt, const char *restrict format) diff --git a/src/lib/libc/stdio/internal/printf_options.c b/src/lib/libc/stdio/internal/printf_options.c index 29d71a1..b6d174d 100644 --- a/src/lib/libc/stdio/internal/printf_options.c +++ b/src/lib/libc/stdio/internal/printf_options.c @@ -1,4 +1,4 @@ -#include +#include static int get_flags(struct printf_opt *opt, const char *restrict format) { diff --git a/src/lib/libc/stdio/printf.c b/src/lib/libc/stdio/printf.c index 33b601e..a67b524 100644 --- a/src/lib/libc/stdio/printf.c +++ b/src/lib/libc/stdio/printf.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int printf(const char *restrict format, ...) { diff --git a/src/lib/libc/stdio/putc.c b/src/lib/libc/stdio/putc.c index 60cfb49..5b2d791 100644 --- a/src/lib/libc/stdio/putc.c +++ b/src/lib/libc/stdio/putc.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int putc(int c) { diff --git a/src/lib/libc/stdio/puts.c b/src/lib/libc/stdio/puts.c index 7c74d24..d11bec8 100644 --- a/src/lib/libc/stdio/puts.c +++ b/src/lib/libc/stdio/puts.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include int puts(const char *s) { diff --git a/src/lib/libc/stdio/snprintf.c b/src/lib/libc/stdio/snprintf.c index 8f8f38e..e983f49 100644 --- a/src/lib/libc/stdio/snprintf.c +++ b/src/lib/libc/stdio/snprintf.c @@ -1,4 +1,4 @@ -#include +#include int snprintf(char *restrict str, size_t size, const char *restrict format, ...) { diff --git a/src/lib/libc/stdio/sprintf.c b/src/lib/libc/stdio/sprintf.c index 5e2c810..22ba62e 100644 --- a/src/lib/libc/stdio/sprintf.c +++ b/src/lib/libc/stdio/sprintf.c @@ -1,4 +1,4 @@ -#include +#include int sprintf(char *restrict str, const char *restrict format, ...) { diff --git a/src/lib/libc/stdio/vdprintf.c b/src/lib/libc/stdio/vdprintf.c index 0826072..a4454a0 100644 --- a/src/lib/libc/stdio/vdprintf.c +++ b/src/lib/libc/stdio/vdprintf.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include // FIXME: // if the writte syscall do not return the same diff --git a/src/lib/libc/stdio/vsnprintf.c b/src/lib/libc/stdio/vsnprintf.c index ff6f42c..6489aeb 100644 --- a/src/lib/libc/stdio/vsnprintf.c +++ b/src/lib/libc/stdio/vsnprintf.c @@ -1,4 +1,4 @@ -#include +#include static void disp_char(struct printf_opt *opt, char n) { diff --git a/src/lib/libc/stdio/vsprintf.c b/src/lib/libc/stdio/vsprintf.c index 76819cb..7c45220 100644 --- a/src/lib/libc/stdio/vsprintf.c +++ b/src/lib/libc/stdio/vsprintf.c @@ -1,4 +1,4 @@ -#include +#include int vsprintf(char *restrict str, const char *restrict format, va_list ap) { diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c new file mode 100644 index 0000000..d00624e --- /dev/null +++ b/src/lib/libc/stdlib/calloc.c @@ -0,0 +1,16 @@ +#include +#include +#include + +void *calloc(size_t nmemb, size_t size) +{ + if (size == 0 || nmemb == 0) + return (NULL); + + void *ret = malloc(nmemb * size); + if (ret == NULL) + return (NULL); + + memset(ret, 0x00, size); + return (ret); +} diff --git a/src/lib/libc/stdlib/free.S b/src/lib/libc/stdlib/free.S new file mode 100644 index 0000000..f580c40 --- /dev/null +++ b/src/lib/libc/stdlib/free.S @@ -0,0 +1,17 @@ +#include +.text +.global _free +.type _free, @function + + +.align 2 +/* +** @note: the MMU is used by Casio so we +** can not implement brk or skr because +** of non continuous heap. +*/ +_free: + trapa #__NR_proc_heap_free + rts + nop +.end diff --git a/src/lib/libc/stdlib/malloc.S b/src/lib/libc/stdlib/malloc.S new file mode 100644 index 0000000..386ef54 --- /dev/null +++ b/src/lib/libc/stdlib/malloc.S @@ -0,0 +1,16 @@ +#include +.text +.global _malloc +.type _malloc, @function + + +.align 2 +/* +** @note: We can not implement brk or skr +** because the MMU is used by Casio. +*/ +_malloc: + trapa #__NR_proc_heap_alloc + rts + nop +.end diff --git a/src/lib/libc/stdlib/realloc.S b/src/lib/libc/stdlib/realloc.S new file mode 100644 index 0000000..5f11849 --- /dev/null +++ b/src/lib/libc/stdlib/realloc.S @@ -0,0 +1,46 @@ +#include +.text +.global _realloc +.type _realloc, @function + +.extern _malloc +.extern _free + +.align 2 +/* +** void *realloc(void ptr, size_t size) +** +** @note: the MMU is used by Casio so we +** can not implement brk or skr because +** of non continuous heap. +*/ +_realloc: + ! Check malloc part + tst r4, r4 ! if ptr == NULL... + bf.s check_free ! ...if not, jump at + mov.l .malloc, r0 ! get malloc() address + jmp @r0 ! call malloc(size) + mov r5, r4 ! (db) send size + + ! Check free +check_free: + tst r5, r5 ! if size == 0... + bf.s call_realloc ! ...if not, jump at + mov.l .free, r0 ! get free() address + sts.l pr, @-r15 ! save pr register + jmp @r0 ! call free(ptr) + nop ! (db) nop + rts ! return... + xor r0, r0 ! (db) ...NULL + + + ! Call realloc +call_realloc: + trapa #__NR_proc_heap_realloc + rts + nop + +.align 4 +.malloc: .long _malloc +.free: .long _free +.end diff --git a/src/lib/libc/stdlib/reallocarray.c b/src/lib/libc/stdlib/reallocarray.c new file mode 100644 index 0000000..044d364 --- /dev/null +++ b/src/lib/libc/stdlib/reallocarray.c @@ -0,0 +1,8 @@ +#include + +//FIXME: check safe !!!! +//FIXME: Check underflow !! +void *reallocarray(void *ptr, size_t nmemb, size_t size) +{ + return (realloc(ptr, nmemb * size)); +} diff --git a/src/lib/libc/string/memcpy.c b/src/lib/libc/string/memcpy.c index f8cc900..98992b3 100644 --- a/src/lib/libc/string/memcpy.c +++ b/src/lib/libc/string/memcpy.c @@ -1,5 +1,4 @@ -#include -#include +#include void *memcpy(void *dest, const void *src, size_t count) { diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c index 6c20f8a..7505a4e 100644 --- a/src/lib/libc/string/memset.c +++ b/src/lib/libc/string/memset.c @@ -1,4 +1,4 @@ -#include +#include //TODO: update me :( void *memset(void *s, int c, size_t n) diff --git a/src/lib/libc/string/strcat.c b/src/lib/libc/string/strcat.c index 5cc1601..ea5df08 100644 --- a/src/lib/libc/string/strcat.c +++ b/src/lib/libc/string/strcat.c @@ -1,4 +1,4 @@ -#include +#include char *strcat(char *dest, char const *src) { diff --git a/src/lib/libc/string/strchr.c b/src/lib/libc/string/strchr.c index 60cadfe..0fd4c1e 100644 --- a/src/lib/libc/string/strchr.c +++ b/src/lib/libc/string/strchr.c @@ -1,4 +1,4 @@ -#include +#include //TODO: asm ? char *strchr(const char *s1, int c) diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c index a69ff88..d3fa79f 100644 --- a/src/lib/libc/string/strcmp.c +++ b/src/lib/libc/string/strcmp.c @@ -1,4 +1,4 @@ -#include +#include int strcmp(const char *s1, const char *s2) { diff --git a/src/lib/libc/string/strcpy.c b/src/lib/libc/string/strcpy.c index a9eb95d..3d80d28 100644 --- a/src/lib/libc/string/strcpy.c +++ b/src/lib/libc/string/strcpy.c @@ -1,4 +1,4 @@ -#include +#include char *strcpy(char *dest, char const *src) { diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c new file mode 100644 index 0000000..6cb18ac --- /dev/null +++ b/src/lib/libc/string/strdup.c @@ -0,0 +1,22 @@ +#include +#include + +char *strdup(const char *s) +{ + size_t len; + void *dump; + + // Check error + if (s == NULL) + return (NULL); + + // Check len + len = strlen(s); + if (len == 0) + return (NULL); + + // Dump string and return + dump = malloc(len); + memcpy(dump, s, len); + return (dump); +} diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c index 63ea05d..b836c2f 100644 --- a/src/lib/libc/string/strlen.c +++ b/src/lib/libc/string/strlen.c @@ -1,4 +1,4 @@ -#include +#include size_t strlen(char const *str) { diff --git a/src/lib/libc/unistd/close.S b/src/lib/libc/unistd/close.S index 0f767e0..c714af5 100644 --- a/src/lib/libc/unistd/close.S +++ b/src/lib/libc/unistd/close.S @@ -1,4 +1,4 @@ -#include +#include .text .global _close .type _close, @function diff --git a/src/lib/libc/unistd/fexecve.S b/src/lib/libc/unistd/fexecve.S index fdba526..27ea598 100644 --- a/src/lib/libc/unistd/fexecve.S +++ b/src/lib/libc/unistd/fexecve.S @@ -1,4 +1,4 @@ -#include +#include .text .global _fexecve .type _fexecve, @function diff --git a/src/lib/libc/unistd/getpgid.S b/src/lib/libc/unistd/getpgid.S index 5b1b5bc..92a284d 100644 --- a/src/lib/libc/unistd/getpgid.S +++ b/src/lib/libc/unistd/getpgid.S @@ -1,4 +1,4 @@ -#include +#include .text .global _getpgid .type _getpgid, @function diff --git a/src/lib/libc/unistd/getpid.S b/src/lib/libc/unistd/getpid.S index d2e2146..4cc19b5 100644 --- a/src/lib/libc/unistd/getpid.S +++ b/src/lib/libc/unistd/getpid.S @@ -1,4 +1,4 @@ -#include +#include .text .global _getpid .type _getpid, @function diff --git a/src/lib/libc/unistd/getppid.S b/src/lib/libc/unistd/getppid.S index ca293d6..ed772d4 100644 --- a/src/lib/libc/unistd/getppid.S +++ b/src/lib/libc/unistd/getppid.S @@ -1,4 +1,4 @@ -#include +#include .text .global _getppid .type _getppid, @function diff --git a/src/lib/libc/unistd/lseek.S b/src/lib/libc/unistd/lseek.S index 3420698..3de4904 100644 --- a/src/lib/libc/unistd/lseek.S +++ b/src/lib/libc/unistd/lseek.S @@ -1,4 +1,4 @@ -#include +#include .text .global _lseek .type _lseek, @function diff --git a/src/lib/libc/unistd/open.S b/src/lib/libc/unistd/open.S index 24dedbf..5c3fe7e 100644 --- a/src/lib/libc/unistd/open.S +++ b/src/lib/libc/unistd/open.S @@ -1,4 +1,4 @@ -#include +#include .text .global _open .type _open, @function diff --git a/src/lib/libc/unistd/read.S b/src/lib/libc/unistd/read.S index a3f9969..53906d0 100644 --- a/src/lib/libc/unistd/read.S +++ b/src/lib/libc/unistd/read.S @@ -1,4 +1,4 @@ -#include +#include .text .global _read .type _read, @function diff --git a/src/lib/libc/unistd/setpgid.S b/src/lib/libc/unistd/setpgid.S index 6b8b82a..8663cf2 100644 --- a/src/lib/libc/unistd/setpgid.S +++ b/src/lib/libc/unistd/setpgid.S @@ -1,4 +1,4 @@ -#include +#include .text .global _setpgid .type _setpgid, @function diff --git a/src/lib/libc/unistd/waitpid.S b/src/lib/libc/unistd/waitpid.S index 631faaa..30c4788 100644 --- a/src/lib/libc/unistd/waitpid.S +++ b/src/lib/libc/unistd/waitpid.S @@ -1,4 +1,4 @@ -#include +#include .text .global _waitpid .type _waitpid, @function diff --git a/src/lib/libc/unistd/write.S b/src/lib/libc/unistd/write.S index db948c2..9091b47 100644 --- a/src/lib/libc/unistd/write.S +++ b/src/lib/libc/unistd/write.S @@ -1,4 +1,4 @@ -#include +#include .text .global _write .type _write, @function diff --git a/src/user/shell/Makefile b/src/user/shell/Makefile index 230b457..52781f6 100644 --- a/src/user/shell/Makefile +++ b/src/user/shell/Makefile @@ -8,7 +8,7 @@ include ../../../global.mk ##--- ## Static variables ##-- -HEADER := -I../../../include -I../../../include/user +HEADER := -I../../../include/lib -I../../../include/user/shell BUILD := ../../../build/user/shell DEBUG := ../../../debug_bin OUTPUT := ../../../output diff --git a/src/user/shell/builtin/fxdb.c b/src/user/shell/builtin/fxdb.c index 2e911fb..288d44a 100644 --- a/src/user/shell/builtin/fxdb.c +++ b/src/user/shell/builtin/fxdb.c @@ -1,7 +1,6 @@ #include "builtin.h" -#include -VHEX_BUILTIN(fxdb) +int builtin_fxdb(int argc, char **argv) { //TODO: handle parameter. (void)argc; diff --git a/src/user/shell/builtin/proc.c b/src/user/shell/builtin/proc.c index 588aa33..ea60503 100644 --- a/src/user/shell/builtin/proc.c +++ b/src/user/shell/builtin/proc.c @@ -1,19 +1,19 @@ -#include -#include -#include -#include +#include +#include +#include "builtin.h" int builtin_proc(void) { + char *argv[2] = {"test", NULL}; pid_t child; int wstatus; - puts("proc test entry :)\n"); - printf(" PPID PID PGID\n"); - printf("%-6d%-6d%-6d\n", getppid(), getpid(), getpgid()); + //puts("proc test entry :)\n"); + //printf(" PPID PID PGID\n"); + //printf("%-6d%-6d%-6d\n", getppid(), getpid(), getpgid()); // Try to create first child - child = fexecve("/mnt/casio/VHEX/test.elf"); + child = fexecve("/mnt/casio/VHEX/test.elf", argv, NULL); if (child == -1) { printf("fexecve fail :(\n"); @@ -21,7 +21,7 @@ int builtin_proc(void) } // Wait child death - waitpid(-1, &wstatus, 0); + waitpid(child, &wstatus, 0); printf("+++ exited with %d +++\n", WEXITSTATUS(wstatus)); return (0); } diff --git a/src/user/shell/main.c b/src/user/shell/main.c index 4b6cbb3..c5ce6ce 100644 --- a/src/user/shell/main.c +++ b/src/user/shell/main.c @@ -1,12 +1,36 @@ -#include -#include +#include +#include +#include #include "util.h" +static int manual_proc_call(char **argv) +{ + char pathname[32]; + int wstatus; + pid_t child; + + // Generate pathname + // TODO: handle PATH + strcpy(pathname, "/mnt/casio/VHEX/"); + strcat(pathname, argv[0]); + + // Try to call binary from eeprom + printf("try to call '%s'\n", pathname); + child = fexecve(pathname, argv, NULL); + if (child != 0) + return (-1); + + waitpid(child, &wstatus, 0); + return (WEXITSTATUS(wstatus)); +} + //TODO: documentation. int main(void) { char input[12]; int cmd_size; + char **argv; + int argc; // Shell main loop. write(STDOUT_FILENO, "Boot Complete !\n", 16); @@ -14,22 +38,27 @@ int main(void) { // Get user command. write(STDOUT_FILENO, ">", 1); + memset(input, 0x00, 12); cmd_size = read(STDIN_FILENO, input, 12); // Check no char if (cmd_size == 1) continue; - // Remove '\n' char. - // FIXME: create argc, argv !! - input[cmd_size - 1] = '\0'; + // Generate argc / argv. + if (strtotab(&argc, &argv, input) != 0) { + printf("parser: internal error\n"); + continue; + } // Check buit-in. - if (check_builtin(input) != 0) - { - write(STDOUT_FILENO, input, cmd_size - 1); - write(STDOUT_FILENO, ": command not found\n", 20); - } + if (check_builtin(argc, argv) != 0 && + manual_proc_call(argv) != 0) + printf("%s: command not found\n", argv[0]); + + // Free argc /argv + // TODO: way better way + strtotab_quit(&argc, &argv); } return (0); } diff --git a/src/user/shell/shell.ld b/src/user/shell/shell.ld index d0505b5..9e95154 100644 --- a/src/user/shell/shell.ld +++ b/src/user/shell/shell.ld @@ -40,12 +40,6 @@ SECTIONS /* ???? */ *(.rofixup) - - /* Internal builtin cache */ - PROVIDE (_builtin_list = ALIGN(4)); - *(.builtin) - *(.builtin.*) - PROVIDE (_builtin_list_end = . ); } > userram /* Relocatable sections */ diff --git a/src/user/shell/util/check_builtin.c b/src/user/shell/util/check_builtin.c index 4b68d12..0742a93 100644 --- a/src/user/shell/util/check_builtin.c +++ b/src/user/shell/util/check_builtin.c @@ -1,8 +1,7 @@ #include "util.h" #include "builtin.h" -#include -#include -#include +#include +#include // Internal builtin list // FIXME: due to PIE binary format, we can not @@ -21,94 +20,15 @@ struct builtin_s builtin[2] = { //TODO: use agc, argv. -int check_builtin(char *cmd) +int check_builtin(int argc, char **argv) { -/* extern struct builtin_s *builtin_list; - extern struct builtin_s *builtin_list_end; - int i; - - // Try to find builtin - i = -1; - while (&builtin_list[++i] < builtin_list_end) + for (int i = 0 ; i < 2 ; ++i) { - // Check builtin name - if (strcmp(builtin_list[i].name, cmd) != 0) - continue; - - // Execute builtin - builtin_list[i].entry(0, NULL); - return (0); - }*/ - for (int i = 0 ; i < 2 ; ++i) { - if (strcmp(builtin[i].name, cmd) != 0) + if (strcmp(builtin[i].name, argv[0]) != 0) continue; if (builtin[i].entry != NULL) - (*builtin[i].entry)(0, NULL); + (*builtin[i].entry)(argc, argv); return (0); } return (-1); - - // Process test -/* dclear(); - dprint(0, 0, "Process Load Test !"); - - // Load process test - pid_t pid = fexecve("/mnt/smemfs/VHEX/test.elf"); - if (pid < 0) - { - dprint(0, 1, "Process error !"); - dupdate(); - for(int i = 0 ; i < 3000000 ; ++i); - return (-1); - } - - int counter = 0; - dclear(); - dprint(0, 0, "Process Test !");; - while (1) - { - dclr_str_area(0, 1, 20, 1); - dprint(0, 1, "P process: %d", counter); - dupdate(); - - counter = counter + 1; - for (int i = 0 ; i < 30000 ; ++i); - } - - //int wstatus; - //pid_t pid; - //int i; -*/ - // Try to find builtin -/* for (int i = 0 ; i < 1 ; i++) - { - if (strcmp(builtin[i].name, cmd) != 0) - continue; - - // Execute builtin - builtin[i].entry(0, NULL); - return (0); - }*/ - return (-1); - // Create subprocess - //pid = fork(); - //if (pid < 0) - // return (1); - - // If we are the child execute - // the builtins. - //if (pid == 0) - // //{ - // dclear(); - // dprint(0, 0, "Child process !!"); - // dprint(0, 1, "PID = %d", getpid()); - // dprint(0, 2, "PPID = %d", getppid()); - // dupdate(); - - // } else { - // waitpid(pid, &wstatus, WCONTINUED); - //TODO: signal handling. - // } - // } - // return (1); } diff --git a/src/user/shell/util/strtotab.c b/src/user/shell/util/strtotab.c index dc8a419..bf0e12f 100644 --- a/src/user/shell/util/strtotab.c +++ b/src/user/shell/util/strtotab.c @@ -1,10 +1,9 @@ -/*# include -# include -# include - -// Internal prototypes. -extern int strtotab(int *argc, char ***argv, char const *str); -extern void strtotab_quit(int *argc, char ***argv); +#include "util.h" +#include +#include +#include +#include +#include // // parser_get_word() @@ -143,4 +142,4 @@ void strtotab_quit(int *argc, char ***argv) // Secure *argv = NULL; *argc = 0; -}*/ +} diff --git a/src/user/test/Makefile b/src/user/test/Makefile index af7ec9e..97779b4 100644 --- a/src/user/test/Makefile +++ b/src/user/test/Makefile @@ -8,7 +8,7 @@ include ../../../global.mk ##--- ## Static variables ##-- -HEADER := -I../../../include -I../../../include/user +HEADER := -I../../../include/lib -I../../../include/user/test LIBS := -L../../lib/ -llibc -ldisplay -lgcc BUILD := ../../../build/user/test DEBUG := ../../../debug_bin diff --git a/src/user/test/test.c b/src/user/test/test.c index 4b5550c..e7dd657 100644 --- a/src/user/test/test.c +++ b/src/user/test/test.c @@ -1,5 +1,6 @@ -#include -#include +#include +#include +#include /*static int tree(const char *pathname) { @@ -28,12 +29,18 @@ return (0); }*/ -int main(void) +int main(int argc, char **argv) { char c[1024]; int ret; int fd; + // Check parameters + for (int i = 0 ; i < argc ; i++) + printf("argv[%d]: %s\n", i, argv[i]); + for(int i = 0 ; i < 3000000 ; ++i); + + // Read test fd = open("/mnt/casio/VHEX/text.txt", O_RDONLY); if (fd < 0) { dprintf(STDERR_FILENO, "unable to open test file\n");