diff --git a/include/kernel/devices/tty.h b/include/kernel/devices/tty.h index 7c1fa29..f007010 100644 --- a/include/kernel/devices/tty.h +++ b/include/kernel/devices/tty.h @@ -23,6 +23,14 @@ struct tty_s char **output; } buffers; + // Window size informations used by the write primitive + struct { + unsigned short ws_col; + unsigned short ws_row; + unsigned short ws_xpixel; + unsigned short ws_ypixel; + } winsize; + // Cursor informations struct { int16_t x; diff --git a/include/kernel/fs/smemfs.h b/include/kernel/fs/smemfs.h index 45d4878..f67ba4d 100644 --- a/include/kernel/fs/smemfs.h +++ b/include/kernel/fs/smemfs.h @@ -64,7 +64,8 @@ struct casio_smem_fragment_s uint16_t data_block_id; // ID of blocks containing data for this fragment uint16_t data_offset; // offset of fragment data in the given block - // WARNING : the size is (real_size-1), so *do not forget* to add 1 to + // WARNING : + // The size is (real_size-1), so *do not forget* to add 1 to // have the real size of data! uint16_t data_size; // size of this fragment data @@ -75,6 +76,7 @@ struct casio_smem_fragment_s typedef struct casio_smem_block_s smemfs_sector_t; typedef struct casio_smem_header_s smemfs_inode_t; typedef struct casio_smem_fragment_s smemfs_fragdata_t; +typedef struct casio_smem_header_s smemfs_header_t; // Define internal superblock diff --git a/include/kernel/process.h b/include/kernel/process.h index b5541ea..1e83494 100644 --- a/include/kernel/process.h +++ b/include/kernel/process.h @@ -22,22 +22,17 @@ struct process // Used when interrupt or exception occur //--- struct { - uint32_t kernel; - uint32_t user; + void *kernel; + void *user; } stack; + //--- // Context management //--- common_context_t context; - //--- - // Private data - //--- - char name[PROCESS_NAME_LENGHT]; - - //--- // Shared (child / parent) data informations //--- @@ -51,11 +46,12 @@ struct process struct dentry *working_dir; FILE tty; + //--- // Signals management. //--- //sighandler_t signal[NSIG]; - + //--- // Virtual / Physical memory management. @@ -67,20 +63,20 @@ struct process //--- struct { struct { - uint32_t user; - uint32_t kernel; + void *user; + void *kernel; struct { - uint32_t user; - uint32_t kernel; + size_t user; + size_t kernel; } size; } stack; struct { - uint32_t start; - uint32_t size; + void *start; + size_t size; } program; struct { - uint32_t start; - uint32_t size; + void *start; + size_t size; } exit; } memory; @@ -89,35 +85,43 @@ struct process // Other process management. //--- struct process *parent; + struct process *sibling; struct process *child; + + + //--- + // Private data + //--- + // Process ID + pid_t pid; + pid_t pgid; + + // Indicate process status + enum { + PROC_INIT, + PROC_RUNNING, + PROC_SLEEP, + PROC_STOP, + PROC_ZOMBIE, + PROC_DEAD + } status; + + // Used to by the _exit() syscall + uint32_t __stat_loc; + + // Used by the allocator struct process *next; }; -// Internal struct used by the -// static process stack -struct process_stack -{ - // Indicate process slot status - enum { - PROC_USED, - PROC_UNUSED - } status; - - // Internal process data - struct process process; -}; - - // Functions. -extern struct process *process_create(const char *name); -extern struct process *process_get(pid_t pid); -extern pid_t process_get_pid(struct process *process); +extern struct process *process_create(void); extern int process_switch(pid_t pid); -// Internal function. -extern pid_t process_alloc(struct process **process); +// Internals +extern struct process *process_alloc(void); +extern struct process *process_get(pid_t pid); extern int process_free(struct process *process); #endif /*__KERNEL_PROCESS_H__*/ diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index 84e476c..d3235c4 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -5,15 +5,12 @@ #include #include -//--- -// -// Vhex part !! -// -//--- // Process -extern pid_t sys_fork(void); extern pid_t sys_getpid(void); extern pid_t sys_getppid(void); +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 void sys_exit(int status); diff --git a/include/kernel/util/types.h b/include/kernel/util/types.h index 8ce8c38..4bb5728 100644 --- a/include/kernel/util/types.h +++ b/include/kernel/util/types.h @@ -26,12 +26,9 @@ typedef enum mpu_e MPU_UNKNOWN, } mpu_t; -typedef int pid_t; +typedef int32_t pid_t; typedef int16_t mode_t; typedef uint16_t dev_t; typedef uint16_t umode_t; -// Force inline function. -#define INLINE __attribute__((always_inline)) inline - #endif /*__TYPES_H__*/ diff --git a/include/kernel/util/unistd_32.h b/include/kernel/util/unistd_32.h index d882e82..93784df 100644 --- a/include/kernel/util/unistd_32.h +++ b/include/kernel/util/unistd_32.h @@ -1,6 +1,9 @@ #ifndef __KERNEL_UNISTD_32_H__ # define __KERNEL_UNISTD_32_H__ +// Define the number of syscall +#define __NR_MAX 14 + // Kernel Test #define __NR_test_syscall 0 @@ -8,27 +11,17 @@ #define __NR_exit 1 #define __NR_fexecve 2 #define __NR_waitpid 3 +#define __NR_wait 4 +#define __NR_getpid 5 +#define __NR_getppid 6 +#define __NR_getpgid 7 +#define __NR_setpgid 8 // VFS -#define __NR_read 4 -#define __NR_write 5 -#define __NR_open 6 -#define __NR_close 7 -#define __NR_lseek 8 - -//-- -// Custom ! -//-- - -// Display -#define __NR_kvram_display 9 -#define __NR_kvram_clear 10 -#define __NR_kvram_print 11 -#define __NR_kvram_ascii 12 -#define __NR_kvram_reverse 13 -#define __NR_kvram_scroll 14 -#define __NR_kvram_clr_str_area 15 - -//TODO: keyboard +#define __NR_read 9 +#define __NR_write 10 +#define __NR_open 11 +#define __NR_close 12 +#define __NR_lseek 13 #endif /*__KERNEL_UNISTD_32_H__*/ diff --git a/include/lib/unistd.h b/include/lib/unistd.h index 64fea56..2858743 100644 --- a/include/lib/unistd.h +++ b/include/lib/unistd.h @@ -17,6 +17,16 @@ #define WNOHANG 0 #define WUNTRACED 1 #define WCONTINUED 2 + +//TODO: move me +#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) +#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8) +#define WEXITSTATUS(status) __WEXITSTATUS(status) + +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); diff --git a/src/kernel/bootstrap/start.c b/src/kernel/bootstrap/start.c index b8ff78c..9cc662a 100644 --- a/src/kernel/bootstrap/start.c +++ b/src/kernel/bootstrap/start.c @@ -76,18 +76,18 @@ static void rom_explore(volatile void *rom, int32_t size) while (size >= 0) { unused = *(volatile uint8_t*)rom; - rom = (void*)((uint32_t)rom + 1024); size = size - 1024; + rom = rom + 1024; } } /* section_execute() - Used to execute contructors and destructors */ static void section_execute(void *bsection, void *esection) { - while ((uintptr_t)bsection < (uintptr_t)esection) + while (bsection < esection) { - ((void (*)(void))*((uint32_t*)bsection))(); - bsection = (void*)((uint32_t)bsection + 4); + ((void (*)(void))*((void**)bsection))(); + bsection = bsection + sizeof(void (*)(void)); } } @@ -107,9 +107,7 @@ int start(void) // Check MPU hardware. current_mpu = mpu_get(); if (current_mpu != MPU_SH7305) - { return (0); - } // Execute constructor. section_execute(&bctors, &ectors); @@ -169,8 +167,8 @@ int start(void) vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); vfs_mkdir("/home", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); vfs_mkdir("/mnt", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - vfs_mkdir("/mnt/smemfs", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - vfs_mount(NULL, "/mnt/smemfs", "smemfs", /*MS_RDONLY*/0, NULL); + vfs_mkdir("/mnt/casio", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + vfs_mount(NULL, "/mnt/casio", "smemfs", /*MS_RDONLY*/0, NULL); // Add devices earlyterm_write("Add devices...\n"); @@ -182,24 +180,10 @@ int start(void) // Start first process ! //--- - // Create first process: Vhex. - //earlyterm_write("Create first process...\n"); - //struct process *vhex_process = process_create("Vhex"); - /*if (vhex_process == NULL) - { - earlyterm_clear(); - earlyterm_write("Vhex fatal error !\n"); - earlyterm_write("First process error !\n"); - earlyterm_write("Press [MENU] key...\n"); - while (1) { __asm__ volatile ("sleep"); } - }*/ - // Load programe. - //vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process); - //if (vhex_process->context.spc == 0x00000000) earlyterm_write("Create first process...\n"); - struct process *vhex_process = process_create("Vhex"); - if (vhex_process == NULL || loader(vhex_process, "/mnt/smemfs/VHEX/shell.elf") != 0) + struct process *vhex_process = process_create(); + if (vhex_process == NULL || loader(vhex_process, "/mnt/casio/VHEX/shell.elf") != 0) { // Display message. earlyterm_clear(); @@ -208,8 +192,8 @@ int start(void) if (vhex_process->context.spc == 0xffffffff) earlyterm_write("process_create() error\n"); else - earlyterm_write("File \"VHEX/shell.elf\" not found !"); - earlyterm_write("Press [MENU key]..."); + earlyterm_write("File \"VHEX/shell.elf\" not found !\n"); + earlyterm_write("Press [MENU key]...\n"); // Restore Casio context. fx9860_context_restore(&casio_context); diff --git a/src/kernel/devices/tty/operations/open.c b/src/kernel/devices/tty/operations/open.c index b7bb37e..365ea09 100644 --- a/src/kernel/devices/tty/operations/open.c +++ b/src/kernel/devices/tty/operations/open.c @@ -26,6 +26,12 @@ void *tty_open(dev_t major, dev_t minor) return (NULL); } + // Generate "visible" informations for the write primitive + tty->winsize.ws_xpixel = screen_get(SCREEN_WIDTH); + tty->winsize.ws_ypixel = screen_get(SCREEN_HEIGHT); + tty->winsize.ws_col = tty->winsize.ws_xpixel / (tty->disp.font->font.width + 1); + tty->winsize.ws_row = tty->winsize.ws_ypixel / (tty->disp.font->font.height + 1); + // Generate formated output buffer indicator tty->cursor.max.x = screen_get(SCREEN_WIDTH) / (tty->disp.font->font.width + 1); tty->cursor.max.y = screen_get(SCREEN_HEIGHT) / (tty->disp.font->font.height + 1); diff --git a/src/kernel/devices/tty/operations/read.c b/src/kernel/devices/tty/operations/read.c index e29d496..5e22851 100644 --- a/src/kernel/devices/tty/operations/read.c +++ b/src/kernel/devices/tty/operations/read.c @@ -90,6 +90,7 @@ ssize_t tty_read(void *inode, void *buffer, size_t count) return (keyboard.buffer.clen); } +//TODO: move me static int check_signal(struct keyboard_obj_s *keyboard, key_t key) { //TODO @@ -98,111 +99,103 @@ static int check_signal(struct keyboard_obj_s *keyboard, key_t key) return (0); } +// TODO: move me +// TODO: update me static int check_special(struct keyboard_obj_s *keyboard, key_t key) { extern fx9860_context_t casio_context; extern fx9860_context_t vhex_context; - switch (key) - { // Check MAJ. - case KEY_ALPHA: - { - keyboard->mode = keyboard->mode ^ 0x02; - return (1); - } + if (key == KEY_ALPHA) { + keyboard->mode = keyboard->mode ^ 0x02; + return (1); + } - // Check Alpha / num mode. - case KEY_SHIFT: - { - keyboard->mode = keyboard->mode ^ 0x01; - return (1); - } + // Check Alpha / num mode. + if (key == KEY_SHIFT) { + keyboard->mode = keyboard->mode ^ 0x01; + return (1); + } // Check DEL key. - case KEY_DEL: - { - // Check potential error. - if (keyboard->buffer.cursor <= 0) - return (1); - - // Move seconde part. - memcpy( - &keyboard->buffer.addr[keyboard->buffer.cursor - 1], - &keyboard->buffer.addr[keyboard->buffer.cursor], - keyboard->buffer.clen - keyboard->buffer.cursor - ); - - // Add null char and update clen. - keyboard->buffer.clen = keyboard->buffer.clen - 1; - keyboard->buffer.addr[keyboard->buffer.clen] = '\0'; - keyboard->buffer.cursor = keyboard->buffer.cursor - 1; + if (key == KEY_DEL) + { + // Check potential error. + if (keyboard->buffer.cursor <= 0) return (1); - } + // Move seconde part. + memcpy( + &keyboard->buffer.addr[keyboard->buffer.cursor - 1], + &keyboard->buffer.addr[keyboard->buffer.cursor], + keyboard->buffer.clen - keyboard->buffer.cursor + ); - // Check MENU key. - // TODO: fix me ! - case KEY_MENU: - { - // Save current Vhex context and restore Casio's context. - atomic_start(); - fx9860_context_save(&vhex_context); - fx9860_context_restore(&casio_context); - atomic_stop(); + // Add null char and update clen. + keyboard->buffer.clen = keyboard->buffer.clen - 1; + keyboard->buffer.addr[keyboard->buffer.clen] = '\0'; + keyboard->buffer.cursor = keyboard->buffer.cursor - 1; + return (1); + } - // Inject MENU key and call GetKey(). - // TODO !!! - //int row = 0; - //int column = 0; - //uint16_t keymatrix = 0x0308; - //casio_Bkey_PutKeymatrix(&keymatrix); - //casio_GetKeyWait(&row, &column, 0, 0, 0, &key); - casio_GetKey(&key); + // Check MENU key. + // TODO: fix me ! + if (key == KEY_MENU) + { + // Save current Vhex context and restore Casio's context. + atomic_start(); + fx9860_context_save(&vhex_context); + fx9860_context_restore(&casio_context); + atomic_stop(); + + // Inject MENU key and call GetKey(). + // TODO !!! + //casio_GetKeyWait(&row, &column, 0, 0, 0, &key); + casio_GetKey(&key); - // Save current Casio's context and restore Vhex's context. - atomic_start(); - fx9860_context_save(&casio_context); - fx9860_context_restore(&vhex_context); - atomic_stop(); - return (1); - } + // Save current Casio's context and restore Vhex's context. + atomic_start(); + fx9860_context_save(&casio_context); + fx9860_context_restore(&vhex_context); + atomic_stop(); + return (1); + } - // Check EXE key. - case KEY_EXE: - { - // Add new line character. - keyboard->buffer.addr[keyboard->buffer.clen] = '\n'; - keyboard->buffer.clen = keyboard->buffer.clen + 1; - keyboard->buffer.addr[keyboard->buffer.clen] = '\0'; + // Check EXE key. + if (key == KEY_EXE) + { + // Add new line character. + keyboard->buffer.addr[keyboard->buffer.clen] = '\n'; + keyboard->buffer.clen = keyboard->buffer.clen + 1; + keyboard->buffer.addr[keyboard->buffer.clen] = '\0'; - // indicate that the EXE has been pressed. - keyboard->mode = keyboard->mode | 0x04; + // indicate that the EXE has been pressed. + keyboard->mode = keyboard->mode | 0x04; + return (1); + } + + // Check LEFT key. + if (key == KEY_LEFT) + { + // Check potential error. + if (keyboard->buffer.cursor <= 0) return (1); - } - // Check LEFT key. - case KEY_LEFT: - { - // Check potential error. - if (keyboard->buffer.cursor <= 0) - return (1); + // Move cursor. + keyboard->buffer.cursor = keyboard->buffer.cursor - 1; + return (1); + } - // Move cursor. - keyboard->buffer.cursor = keyboard->buffer.cursor - 1; + // Check RIGHT key. + if (key == KEY_RIGHT) + { + // Check limit + if (keyboard->buffer.cursor >= keyboard->buffer.clen) return (1); - } - - // Check RIGHT key. - case KEY_RIGHT: - { - if (keyboard->buffer.cursor >= keyboard->buffer.clen) - return (1); - // Move cursor. - keyboard->buffer.cursor = keyboard->buffer.cursor + 1; - return (1); - } - default: break; + // Move cursor. + keyboard->buffer.cursor = keyboard->buffer.cursor + 1; + return (1); } return (0); } @@ -323,12 +316,13 @@ static void cursor_callback(struct keyboard_obj_s *keyboard) y = y * (keyboard->tty->disp.font->font.height + 1); // Display cursor. - dreverse( + /* dreverse( &keyboard->tty->disp, x, y, (keyboard->tty->disp.font->font.width + 1), (keyboard->tty->disp.font->font.height + 1) ); (*screen_update)(keyboard->tty->disp.vram); +*/ // Restore TTY cursor position keyboard->tty->cursor.x = sttyx; diff --git a/src/kernel/devices/tty/operations/write.c b/src/kernel/devices/tty/operations/write.c index c70f3db..b5e57ea 100644 --- a/src/kernel/devices/tty/operations/write.c +++ b/src/kernel/devices/tty/operations/write.c @@ -7,7 +7,7 @@ static void tty_vertical_update(struct tty_s *tty) { // Get next line. - if (tty->cursor.y + 1 <= tty->cursor.max.y) + if (tty->cursor.y + 1 < tty->cursor.max.y) tty->cursor.y = tty->cursor.y + 1; else tty->cursor.y = 0; @@ -117,7 +117,7 @@ static void tty_display(struct tty_s *tty) // @note: circular buffer. line = 0; start = tty->cursor.y; - while (++line < tty->cursor.max.y) + while (++line < tty->winsize.ws_row) { // Update check line. saved_start = start; diff --git a/src/kernel/fs/smemfs/file/read.c b/src/kernel/fs/smemfs/file/read.c index a3e828a..9ce5e6a 100644 --- a/src/kernel/fs/smemfs/file/read.c +++ b/src/kernel/fs/smemfs/file/read.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -13,51 +14,64 @@ static void *casio_smem_get_data_base_address(smemfs_fragdata_t *fragment) while (block->magic_start == CASIO_SMEM_BLOCK_ENTRY_MAGIC && block->info.id != fragment->data_block_id) { - block = block + 1; + block = &block[1]; } if (block->info.id != fragment->data_block_id) return (NULL); - return ((void *)(uint32_t)(block->offset + fragment->data_offset)); + return ((void *)(block->offset + fragment->data_offset)); } /* casio_smem_read() - Read the file data (based on internal cursor) */ ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos) { smemfs_fragdata_t *fragment; + smemfs_header_t *header; off_t fragment_data_offset; void *data_base_addr; - ssize_t current_size; + size_t current_size; size_t real_size; // Get Check obvious error. if (inode == NULL || buf == NULL) return (-1); + // Check file type + header = inode; + if (header->info != CASIO_SMEM_HEADER_INFO_EXIST || + header->type != CASIO_SMEM_HEADER_TYPE_FILE) { + earlyterm_write("smemfs: header error !\n"); + return (-1); + } + // Start atomic operation atomic_start(); // Get the current data fragment. current_size = 0; - fragment = (void *)((uint32_t)inode + sizeof(struct casio_smem_header_s)); + fragment = inode + sizeof(struct casio_smem_header_s); while (fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC && - pos > (off_t)(current_size + fragment->data_size + 1)) + fragment->info == CASIO_SMEM_FRAGMENT_INFO_EXIST && + (off_t)(current_size + fragment->data_size + 1) < pos) { current_size = current_size + fragment->data_size + 1; - fragment = fragment + 1; + fragment = &fragment[1]; } // Check fragment error - if (fragment->magic != CASIO_SMEM_FRAGMENT_MAGIC) + if (fragment->magic != CASIO_SMEM_FRAGMENT_MAGIC || + fragment->info != CASIO_SMEM_FRAGMENT_INFO_EXIST) { atomic_stop(); + earlyterm_write("smemfs: fragment error !\n"); return (-1); } // Read file data current_size = 0; fragment_data_offset = pos - current_size; - while (current_size < (ssize_t)count && - fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC) + while (current_size < count && + fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC && + fragment->info == CASIO_SMEM_FRAGMENT_INFO_EXIST) { // Calculate the real size to read. real_size = fragment->data_size + 1 - fragment_data_offset; @@ -72,16 +86,16 @@ ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos) // Handle fragment data offset. if (fragment_data_offset != 0) { - data_base_addr = (void *)(((uint32_t)data_base_addr) + fragment_data_offset); + data_base_addr = data_base_addr + fragment_data_offset; fragment_data_offset = 0; } // Fill the buffer - memcpy((void*)(buf + current_size), (void*)(0xa0000000 + data_base_addr), real_size); + memcpy(buf + current_size, (void*)(0xa0000000 + data_base_addr), real_size); // Update informations. current_size = current_size + real_size; - fragment = fragment + 1; + fragment = &fragment[1]; } // Stop atomic operation diff --git a/src/kernel/fs/smemfs/inode/walk.c b/src/kernel/fs/smemfs/inode/walk.c index 7b42da7..58ea75e 100644 --- a/src/kernel/fs/smemfs/inode/walk.c +++ b/src/kernel/fs/smemfs/inode/walk.c @@ -3,37 +3,34 @@ /* smemfs_walk() - Find inode based on directory ID and flags */ /* @note: This function is internal of smemFS, do not call it ! */ smemfs_inode_t *smemfs_walk(smemfs_inode_t *current, - smemfs_inode_t *entry, uint16_t folder_id, int flags) + smemfs_inode_t *file, uint16_t folder_id, int flags) { smemfs_fragdata_t *fragdata; // Check current inode validity. - if (entry == NULL) + if (file == NULL) return (NULL); - // Walk entry - while (entry->info == CASIO_SMEM_HEADER_INFO_EXIST || - entry->info == CASIO_SMEM_HEADER_INFO_DELETE) + // Walk file + while (file->info == CASIO_SMEM_HEADER_INFO_EXIST || + file->info == CASIO_SMEM_HEADER_INFO_DELETE) { // New inode validity check. - if (entry != current && - entry->info == CASIO_SMEM_HEADER_INFO_EXIST && - (((flags & WALK_FLAG_ID_CHECK_PARENT) != 0 && entry->parent.id == folder_id) || - ((flags & WALK_FLAG_ID_CHECK_PARENT) == 0 && entry->id == folder_id))) + if (file != current && + file->info == CASIO_SMEM_HEADER_INFO_EXIST && + (((flags & WALK_FLAG_ID_CHECK_PARENT) != 0 && file->parent.id == folder_id) || + ((flags & WALK_FLAG_ID_CHECK_PARENT) == 0 && file->id == folder_id))) { - return (entry); + return (file); } // Fast fragmentation skip - fragdata = (void *)((uint32_t)(entry) + sizeof(struct casio_smem_header_s)); + fragdata = (void *)&file[1]; if (fragdata->magic == CASIO_SMEM_FRAGMENT_MAGIC) - { - fragdata = (void *)((uint32_t)fragdata + - (sizeof(struct casio_smem_fragment_s) * fragdata->frag_total)); - } + fragdata = &fragdata[fragdata->frag_total]; // Update current inode - entry = (void*)fragdata; + file = (void*)fragdata; } return (NULL); } diff --git a/src/kernel/fs/vfs/dentry/resolve.c b/src/kernel/fs/vfs/dentry/resolve.c index e6cbca3..c830d0a 100644 --- a/src/kernel/fs/vfs/dentry/resolve.c +++ b/src/kernel/fs/vfs/dentry/resolve.c @@ -39,7 +39,7 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode) // Check VFS validity if (vfs_root_node == NULL) { - earlyterm_write("VFS root error !"); + earlyterm_write("VFS root error !\n"); DBG_WAIT; return (NULL); } @@ -105,10 +105,10 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode) next = vfs_dentry_find_next_sibling(next); if (next == NULL) { - earlyterm_write("vfs_resolve(): sibling error !"); - earlyterm_write("* old next: %s$", tmp->name); - earlyterm_write("* file: %s$", file->name); - earlyterm_write("* name: %s$", name); + earlyterm_write("vfs_resolve(): sibling error !\n"); + earlyterm_write("* old next: %s$\n", tmp->name); + earlyterm_write("* file: %s$\n", file->name); + earlyterm_write("* name: %s$\n", name); DBG_WAIT; return (NULL); } @@ -124,7 +124,7 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode) if ((file->mode & __S_IFDIR) == 0) { // Debug ! - earlyterm_write("vfs_resolve(): dir error !"); + earlyterm_write("vfs_resolve(): dir error !\n"); DBG_WAIT; return (NULL); } diff --git a/src/kernel/loader/entry.c b/src/kernel/loader/entry.c index 4e8d9ed..57e41ee 100644 --- a/src/kernel/loader/entry.c +++ b/src/kernel/loader/entry.c @@ -11,13 +11,14 @@ int loader(struct process *process, const char *path) { Elf32_Ehdr header; FILE file; + int err; // Check error and try to open the file. if (process == NULL || vfs_open(&file, path, O_RDONLY) != 0) { - earlyterm_write("loader: Fault error !"); - earlyterm_write("* path: %s$", path); - earlyterm_write("* process: %p", process); + earlyterm_write("loader: Fault error !\n"); + earlyterm_write("* path: %s$\n", path); + earlyterm_write("* process: %p\n", process); DBG_WAIT; return (-1); } @@ -25,25 +26,43 @@ int loader(struct process *process, const char *path) //@NOTE: Only ELF supported !!! // Get / Check ELF header // FIXME: return the file type (elf, g1a, bin, ...) - if (loader_get_header(&file, &header) != 0) + err = loader_get_header(&file, &header); + if (err != 0) { - earlyterm_write("loader: ELF file header error !"); + earlyterm_write("loader: ELF file header error ! (%d)\n", err); + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; DBG_WAIT; return (-2); } // Get / Check program validity - if (loader_load_image(process, &file, &header) != 0) + err = loader_load_image(process, &file, &header); + if (err != 0) { - earlyterm_write("loader: ELF file image error !"); + earlyterm_write("loader: ELF file image error ! (%d)\n", err); + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; DBG_WAIT; return (-3); } // Relocalise sections / symbols - if (loader_reloc_sym(process, &file, &header) != 0) + err = loader_reloc_sym(process, &file, &header); + if (err != 0) { - earlyterm_write("loader: ELF relo error !"); + earlyterm_write("loader: ELF relo error ! (%d)\n", err); + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; + DBG_WAIT; DBG_WAIT; return (-4); } diff --git a/src/kernel/loader/header.c b/src/kernel/loader/header.c index 827bc93..a790a09 100644 --- a/src/kernel/loader/header.c +++ b/src/kernel/loader/header.c @@ -19,18 +19,20 @@ int loader_get_header(FILE *file, Elf32_Ehdr *header) if (header->e_ident[EI_CLASS] != ELFCLASS32) return (-3); - //TODO: Check OSABI (?) + // Check data encoding + if (header->e_ident[EI_DATA] != ELFDATA2MSB) + return (-4); // Check ELF type. if (header->e_type != ET_DYN) - return (-4); + return (-5); // Check ELF specifique instruction if (header->e_machine != EM_SH) - return (-5); + return (-6); // Check ELF version if (header->e_version != EV_CURRENT) - return (-6); + return (-7); return (0); } diff --git a/src/kernel/loader/image.c b/src/kernel/loader/image.c index 6ea6e34..adc761a 100644 --- a/src/kernel/loader/image.c +++ b/src/kernel/loader/image.c @@ -7,7 +7,7 @@ int loader_load_image(struct process *process, FILE *file, Elf32_Ehdr *header) { Elf32_Phdr program; - uint32_t paddress; + void *paddress; uint16_t i; // Walk one time to get program size and @@ -31,7 +31,7 @@ int loader_load_image(struct process *process, FILE *file, Elf32_Ehdr *header) // Allocate programe space into // physical memory. - process->memory.program.start = (uint32_t)pm_alloc(process->memory.program.size); + process->memory.program.start = (void *)pm_alloc(process->memory.program.size); if (process->memory.program.start == 0x00000000) return (-3); @@ -49,11 +49,11 @@ int loader_load_image(struct process *process, FILE *file, Elf32_Ehdr *header) // p_filesz can be smaller than p_memsz so, we need to wipe the area // before the dump. - memset((void *)paddress, 0, program.p_memsz); + memset(paddress, 0, program.p_memsz); // Dump the program. vfs_lseek(file, program.p_offset, SEEK_SET); - vfs_read(file, (void *)paddress, program.p_filesz); + vfs_read(file, paddress, program.p_filesz); } // Generate program entry address diff --git a/src/kernel/loader/reloc_sym.c b/src/kernel/loader/reloc_sym.c index abab06b..2024f51 100644 --- a/src/kernel/loader/reloc_sym.c +++ b/src/kernel/loader/reloc_sym.c @@ -9,10 +9,14 @@ static char *get_shstrtab(FILE *file, Elf32_Ehdr *header) char *shstrtab; // Get sections string header tables - vfs_lseek(file, header->e_shoff + (header->e_shstrndx * sizeof(shdr)), SEEK_SET); - if (vfs_read(file, &shdr, sizeof(shdr)) != sizeof(shdr)) + earlyterm_write( + "off_t = %#x\noff_t = %#x\n", + header->e_shoff + (header->e_shstrndx * sizeof(Elf32_Shdr)), + vfs_lseek(file, header->e_shoff + (header->e_shstrndx * sizeof(Elf32_Shdr)), SEEK_SET) + );; + if (vfs_read(file, &shdr, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)) { - earlyterm_write("loader_relo_sym: section header table error\n"); + earlyterm_write("relo_sym: section header table error\n"); return (NULL); } @@ -20,7 +24,7 @@ static char *get_shstrtab(FILE *file, Elf32_Ehdr *header) shstrtab = (char*)pm_alloc(shdr.sh_size); if (shstrtab == NULL) { - earlyterm_write("loader_relo_sym: memory error\n"); + earlyterm_write("relo_sym: mem error (%d)\n", shdr.sh_size); return (NULL); } @@ -28,7 +32,7 @@ static char *get_shstrtab(FILE *file, Elf32_Ehdr *header) vfs_lseek(file, shdr.sh_offset, SEEK_SET); if (vfs_read(file, shstrtab, shdr.sh_size) != (ssize_t)shdr.sh_size) { - earlyterm_write("loader_relo_sym: shstrtab size error\n"); + earlyterm_write("relo_sym: shstrtab size error\n"); pm_free(shstrtab); return (NULL); } @@ -45,16 +49,16 @@ static int reloc_section(struct process *process, FILE *file, Elf32_Shdr *shdr) for (uint32_t i = 0 ; i < shdr->sh_size / shdr->sh_entsize ; ++i) { // Get relocatable entry - vfs_lseek(file, shdr->sh_offset + (i * sizeof(rela)), SEEK_SET); - if (vfs_read(file, &rela, sizeof(rela)) != sizeof(rela)) + vfs_lseek(file, shdr->sh_offset + (i * sizeof(Elf32_Rela)), SEEK_SET); + if (vfs_read(file, &rela, sizeof(Elf32_Rela)) != sizeof(Elf32_Rela)) { - earlyterm_write("reloc_section: reloc section size error\n"); + earlyterm_write("relo_sym: reloc section size error\n"); return (-1); } // Relocalise symbols //earlyterm_write("* [%d] %p, %#x\n", i, rela.r_offset, rela.r_addend); - prog[rela.r_offset >> 2] = rela.r_addend + process->memory.program.start; + prog[rela.r_offset >> 2] += (uint32_t)process->memory.program.start; //DBG_WAIT; } return (0); @@ -69,8 +73,10 @@ int loader_reloc_sym(struct process *process, FILE *file, Elf32_Ehdr *header) (void)process; // DEBUG - //earlyterm_write("e_shnum = %d\n", header->e_shnum); - //earlyterm_write("e_shstrndx = %d\n", header->e_shstrndx); + earlyterm_write("e_shoff = %d\n", header->e_shoff); + earlyterm_write("e_shnum = %d\n", header->e_shnum); + earlyterm_write("e_shstrndx = %d\n", header->e_shstrndx); + //DBG_WAIT; // Get the shstrtab @@ -82,10 +88,13 @@ int loader_reloc_sym(struct process *process, FILE *file, Elf32_Ehdr *header) for (int i = 1 ; i < header->e_shnum ; ++i) { // Get next section header - vfs_lseek(file, header->e_shoff + (i * sizeof(shdr)), SEEK_SET); - if (vfs_read(file, &shdr, sizeof(shdr)) != sizeof(shdr)) + vfs_lseek(file, header->e_shoff + (i * sizeof(Elf32_Shdr)), SEEK_SET); + if (vfs_read(file, &shdr, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)) { earlyterm_write("loader_reloc_sym: section header\n"); + earlyterm_write("loader_reloc_sym: shoff = %#x\n", header->e_shoff); + earlyterm_write("loader_reloc_sym: shnum = %#x\n", header->e_shnum); + earlyterm_write("loader_reloc_sym: off = %#x\n", header->e_shoff + (i * sizeof(Elf32_Shdr))); return (-2); } @@ -100,8 +109,8 @@ int loader_reloc_sym(struct process *process, FILE *file, Elf32_Ehdr *header) } pm_free(shstrtab); //earlyterm_write("start = %p\n", process->memory.program.start); - //DBG_WAIT; - //DBG_WAIT; + DBG_WAIT; + DBG_WAIT; //DBG_WAIT; return (0); } diff --git a/src/kernel/scheduler/add_task.c b/src/kernel/scheduler/add_task.c index 48e1d19..c12f03f 100644 --- a/src/kernel/scheduler/add_task.c +++ b/src/kernel/scheduler/add_task.c @@ -35,6 +35,9 @@ int sched_add_task(struct process *process) return (-2); } + // Change process status + process->status = PROC_RUNNING; + // Initialize new task // TODO: update quantum ticks management sched_slot->priority._static = SCHED_QUANTUM_TICKS; diff --git a/src/kernel/scheduler/initialize.c b/src/kernel/scheduler/initialize.c index b8666ea..d92d6bc 100644 --- a/src/kernel/scheduler/initialize.c +++ b/src/kernel/scheduler/initialize.c @@ -19,7 +19,7 @@ void sched_initialize(void) } // Initialize internal process informations - // @note: + // TODO ? // * process_sched_current Used by the kernel to handle // interrupt / exception // * process_user_current Used by the kernel to allow diff --git a/src/kernel/scheduler/process/alloc.c b/src/kernel/scheduler/process/alloc.c index 9de6c68..630d80f 100644 --- a/src/kernel/scheduler/process/alloc.c +++ b/src/kernel/scheduler/process/alloc.c @@ -1,20 +1,61 @@ #include +#include +#include +#include -// This function SHOULD NOT be called -// without atomic operation !! -// TODO: dynamic allocation ? -pid_t process_alloc(struct process **process) +// TODO: return EAGAIN !! +// TODO: return ENOMEM !! +struct process *process_alloc(void) { - extern struct process_stack process_stack[PROCESS_MAX]; + extern struct process *proc_table; + extern uint32_t proc_table_max; + uint32_t proc_table_idx; + struct process **proc; - for (int i = 0 ; i < PROCESS_MAX ; i = i + 1) + // Start atomic operation + atomic_start(); + + // Try to find free slot + proc = &proc_table; + proc_table_idx = -1; + while (++proc_table_idx < proc_table_max && *proc != NULL) { - if (process_stack[i].status == PROC_UNUSED) - { - process_stack[i].status = PROC_USED; - *process = &process_stack[i].process; - return (i); + // Check free slot + if ((*proc)->status != PROC_DEAD) { + proc = &(*proc)->next; + continue; } + + // Indicate init phase, stop atomic + // operations and return the process + (*proc)->status = PROC_INIT; + (*proc)->pgid = 0; + atomic_stop(); + return (*proc); } - return (-1); + + // Check error + if (proc_table_idx >= proc_table_max) { + earlyterm_write("proc_alloc: EAGAIN !\n"); + atomic_stop(); + return (NULL); + } + + // Alloc new process manually + *proc = (struct process *)pm_alloc(sizeof(struct process)); + if (*proc == NULL) { + earlyterm_write("proc_alloc: ENOMEM !\n"); + atomic_stop(); + return (NULL); + } + + // Init and return the now process + (*proc)->status = PROC_INIT; + (*proc)->pid = proc_table_idx + 1; + (*proc)->pgid = 0; + (*proc)->next = NULL; + + // Stop atomic operations + atomic_stop(); + return (*proc); } diff --git a/src/kernel/scheduler/process/create.c b/src/kernel/scheduler/process/create.c index e3f1c94..5f6c5a0 100644 --- a/src/kernel/scheduler/process/create.c +++ b/src/kernel/scheduler/process/create.c @@ -4,19 +4,14 @@ #include #include -struct process *process_create(const char *name) +struct process *process_create(void) { extern struct process *process_current; extern struct dentry *vfs_root_node; struct process *process; - pid_t process_pid; - - // Check error - if (name == NULL) - return (NULL); // Try to find free slot. - process_pid = process_alloc(&process); + process = process_alloc(); if (process == NULL) { earlyterm_write("proc_error: alloc error !"); @@ -26,7 +21,7 @@ struct process *process_create(const char *name) // Initialize user stack process->memory.stack.size.user = PROCESS_USER_STACK_SIZE; - process->memory.stack.user = (uint32_t)pm_alloc(process->memory.stack.size.user); + process->memory.stack.user = (void *)pm_alloc(process->memory.stack.size.user); if (process->memory.stack.user == 0x00000000) { earlyterm_write("proc_error: user stack error !"); @@ -34,11 +29,11 @@ struct process *process_create(const char *name) process_free(process); return (NULL); } - process->context.reg[15] = process->memory.stack.user + process->memory.stack.size.user; + process->context.reg[15] = (uint32_t)process->memory.stack.user + process->memory.stack.size.user; // Initialize kernel stack process->memory.stack.size.kernel = PROCESS_KERNEL_STACK_SIZE; - process->memory.stack.kernel = (uint32_t)pm_alloc(process->memory.stack.size.kernel); + process->memory.stack.kernel = (void *)pm_alloc(process->memory.stack.size.kernel); if (process->memory.stack.kernel == 0x00000000) { earlyterm_write("proc_error: kernel stack error !"); @@ -51,26 +46,23 @@ struct process *process_create(const char *name) // initialize "exit" part. uint8_t callexit[8] = { - 0b00100100, 0b01001010, // xor r4, r4 + 0b01100100, 0b00000011, // mov r0, r4 0b11000011, __NR_exit, // trapa #__NR_exit 0b10110000, 0b00000100, // bsr PC + 2 - 4 0b00000000, 0b00001001 // nop }; process->memory.exit.size = 8; - process->memory.exit.start = (uint32_t)(pm_alloc(process->memory.exit.size)); + process->memory.exit.start = (void *)pm_alloc(process->memory.exit.size); if (process->memory.exit.start == 0x00000000) { - pm_free((void *)process->memory.stack.user); - pm_free((void *)process->memory.stack.kernel); + pm_free(process->memory.stack.user); + pm_free(process->memory.stack.kernel); process_free(process); return (NULL); } - process->context.pr = process->memory.exit.start; + process->context.pr = (uint32_t)process->memory.exit.start; memcpy((void *)process->memory.exit.start, callexit, 6); - // Set process name. - strncpy(process->name, name, PROCESS_NAME_LENGHT); - // Initialize context. for (int i = 0 ; i < 15 ; i = i + 1) process->context.reg[i] = 0x00000000; @@ -107,7 +99,7 @@ struct process *process_create(const char *name) // The new process will be visible only // when it is registered by the sheduler. process->parent = process_current; + process->sibling = NULL; process->child = NULL; - process->next = NULL; return (process); } diff --git a/src/kernel/scheduler/process/free.c b/src/kernel/scheduler/process/free.c index b053c18..e133632 100644 --- a/src/kernel/scheduler/process/free.c +++ b/src/kernel/scheduler/process/free.c @@ -1,14 +1,20 @@ #include +//TODO: free allocated proc ? int process_free(struct process *process) { - extern struct process_stack process_stack[PROCESS_MAX]; + extern struct process *proc_table; + extern uint32_t proc_table_max; + uint32_t proc_table_idx; + struct process *proc; - for (int i = 0 ; i < PROCESS_MAX ; i = i + 1) + proc = proc_table; + proc_table_idx = 0; + while (proc != NULL && ++proc_table_idx < proc_table_max) { - if (&process_stack[i].process == process) + if (proc == process) { - process_stack[i].status = PROC_UNUSED; + proc->status = PROC_DEAD; return (0); } } diff --git a/src/kernel/scheduler/process/get.c b/src/kernel/scheduler/process/get.c index 9f8e5ae..8462221 100644 --- a/src/kernel/scheduler/process/get.c +++ b/src/kernel/scheduler/process/get.c @@ -1,27 +1,38 @@ -#include +#include +#include -struct process *process_get_proc(pid_t pid) +struct process *process_get(pid_t pid) { - extern struct process_stack process_stack[PROCESS_MAX]; + extern struct process *proc_table; + struct process *proc; // Check error - if (pid < 0 || pid >= PROCESS_MAX) + if (pid <= 0) return (NULL); - // Return process. - return (&process_stack[pid].process); -} + // Start atomic operation + atomic_start(); -pid_t process_get_pid(struct process *target) -{ - extern struct process_stack process_stack[PROCESS_MAX]; - int i; - - i = -1; - while (++i < PROCESS_MAX) + // Proess table walk + proc = proc_table; + while (proc != NULL) { - if (&process_stack[i].process == target) - return (i); + // Check target process + if (proc->pid != pid) { + proc = proc->next; + continue; + } + + // Check if the process is alive + if (proc->status == PROC_DEAD) + proc = NULL; + + // Stop atomic operations + atomic_stop(); + return (proc); } - return (-1); + + // Stop atomic operation + atomic_stop(); + return (NULL); } diff --git a/src/kernel/scheduler/process/initialize.c b/src/kernel/scheduler/process/initialize.c index f36fa8f..22ad1b3 100644 --- a/src/kernel/scheduler/process/initialize.c +++ b/src/kernel/scheduler/process/initialize.c @@ -1,15 +1,17 @@ #include -// Create all internal global -// used to handle process. -struct process_stack process_stack[PROCESS_MAX]; +// Internal symbols +struct process *proc_table; +uint32_t proc_table_max; __attribute__((constructor)) void process_constructor(void) { - // Set all process to idle state. - for (int i = 0 ; i < PROCESS_MAX ; i = i + 1) - { - process_stack[i].status = PROC_UNUSED; - } + // Initialise dynamic process list + // TODO: + // get the scheduler timing and set the maximal + // number of processes which can be running in the + // same time. + proc_table = NULL; + proc_table_max = PROCESS_MAX; } diff --git a/src/kernel/scheduler/schedule.c b/src/kernel/scheduler/schedule.c index 819663b..05dac4b 100644 --- a/src/kernel/scheduler/schedule.c +++ b/src/kernel/scheduler/schedule.c @@ -6,12 +6,46 @@ int sched_schedule(common_context_t **context_current, common_context_t **contex { extern struct sched_task *sched_task_current; extern struct sched_task *sched_task_queue; - struct sched_task *task_current; + extern struct process *process_current; struct sched_task *task_next; - + + // Get the potential next process context + task_next = sched_task_queue; + if (sched_task_current != NULL && sched_task_current->next != NULL) + task_next = sched_task_current->next; + + // Check / update next task + while (task_next != sched_task_current) + { + // Check process validity + if (task_next->process->status == PROC_RUNNING) + break; + + // Get next task + task_next = task_next->next; + if (task_next == NULL) + task_next = sched_task_queue; + } + + // Check error + if (task_next == sched_task_current) + return (-1); + + // Get contexts + *context_current = NULL; + if (sched_task_current != NULL) + *context_current = &sched_task_current->process->context; + *context_next = &task_next->process->context; + + // Update scheduler task / process current + sched_task_current = task_next; + process_current = sched_task_current->process; + return (0); + + // Check current task // TODO: check process status !! - if (sched_task_current == NULL) +/* if (sched_task_current == NULL) { task_current = NULL; task_next = (sched_task_queue != NULL) ? sched_task_queue : NULL; @@ -28,11 +62,12 @@ int sched_schedule(common_context_t **context_current, common_context_t **contex // Update internal scheduler task cursor sched_task_current = task_next; + process_current = sched_task_current->process; // Get context *context_current = (task_current != NULL) ? &task_current->process->context : NULL; *context_next = &task_next->process->context; - +*/ // DEBUG ! /*kvram_clear(); printk(0, 0, "Scheduler_schudele !"); @@ -42,5 +77,5 @@ int sched_schedule(common_context_t **context_current, common_context_t **contex printk(0, 4, "context next = %p", *context_next); kvram_display(); DBG_WAIT;*/ - return (0); + //return (0); } diff --git a/src/kernel/scheduler/syscall/sys_exit.c b/src/kernel/scheduler/syscall/sys_exit.c index f492d1a..a71affc 100644 --- a/src/kernel/scheduler/syscall/sys_exit.c +++ b/src/kernel/scheduler/syscall/sys_exit.c @@ -1,14 +1,35 @@ #include +#include #include +#include +// TODO: remove / move me ? +#include void sys_exit(int status) { - // TODO handle status - (void)status; + extern struct process *process_current; // Fow now, just wait manual reset... - earlyterm_clear(); - earlyterm_write("PROCESS EXIT SYSCALL !!!!"); - earlyterm_write("Wait manual reset..."); + //earlyterm_clear(); + //earlyterm_write("PROCESS EXIT SYSCALL !!!!\n"); + //earlyterm_write("Wait manual reset..."); + + // Start atomic operation + atomic_start(); + + // Generate stat_loc + process_current->__stat_loc = __W_EXITCODE(status, 0); + + // Frre'd all allocated space + pm_free(process_current->memory.stack.user); + pm_free(process_current->memory.stack.kernel); + pm_free(process_current->memory.program.start); + pm_free(process_current->memory.exit.start); + + // Change process state + process_current->status = PROC_ZOMBIE; + + // Stop atomic operation + atomic_stop(); while (1); } diff --git a/src/kernel/scheduler/syscall/sys_fexecve.c b/src/kernel/scheduler/syscall/sys_fexecve.c index a2c4b10..85341e7 100644 --- a/src/kernel/scheduler/syscall/sys_fexecve.c +++ b/src/kernel/scheduler/syscall/sys_fexecve.c @@ -5,6 +5,9 @@ #include #include +//TODO +//TODO COPY-ON-WRITE !! +//TODO static void proc_dump_shared(struct process *child, struct process *parent) { // Dump all opened file @@ -18,17 +21,20 @@ static void proc_dump_shared(struct process *child, struct process *parent) memcpy(&child->tty, &parent->tty, sizeof(FILE)); } +//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) { extern struct process *process_current; struct process *proc; - pid_t child_pid; // Start atomic operation atomic_start(); // Try create new process - proc = process_create(pathname); + proc = process_create(); if (proc == NULL) { earlyterm_write("sys_fexecve: process_create error !\n"); @@ -51,6 +57,10 @@ pid_t sys_fexecve(const char *pathname) return (-1); } + // Release child process + proc->sibling = process_current->child; + process_current->child = proc; + // Add new process into task queue if (sched_add_task(proc)) { @@ -61,15 +71,12 @@ pid_t sys_fexecve(const char *pathname) return (-1); } - // Get child process PID - child_pid = process_get_pid(proc); - // Debug - earlyterm_write("New proc sched added !"); - earlyterm_write("New proc PID = %#x !", child_pid); - DBG_WAIT; + //earlyterm_write("New proc sched added !\n"); + ///earlyterm_write("New proc PID = %#x !\n", proc->pid); + //DBG_WAIT; // Stop atomic operations atomic_stop(); - return (child_pid); + return (proc->pid); } diff --git a/src/kernel/scheduler/syscall/sys_fork.c b/src/kernel/scheduler/syscall/sys_fork.c deleted file mode 100644 index 16f9167..0000000 --- a/src/kernel/scheduler/syscall/sys_fork.c +++ /dev/null @@ -1,42 +0,0 @@ -/*#include - -pid_t sys_fork(void) -{ - extern struct process *process_current; - struct process *process_new; - pid_t process_new_pid; - - // Check error - if (process_current == NULL) - return (-1); - - // Get the new process slot. - new_pid = process_alloc(&process_new); - if (new_pid != 0) - return (-1); - - // Try to create user stack - process_new->memory.stack.size.user = process_current->; - process_new->memory.stack.user = (uint32_t)pm_alloc(process_new->memory.stack.size.user); - if (process_new->memory.stack.user == 0x00000000) - { - process_free(process_new); - return (-1); - } - - // Try to create kernel stack - process_new->memory.stack.size.kernel = process_current->memory.stack.size.kernel; - process_new->memory.stack.kernel = (uint32_t)pm_alloc(process_new->memory.stack.size.kernel); - if (process_new->memory.stack.kernel == 0x00000000) - { - pm_free(process_new->memory.stack.user); - process_free(process_new); - return (-1); - } - - - //TODO: dump stack data - //TODO: dump code data - //TODO: Initialize context. - return (-1); -}*/ diff --git a/src/kernel/scheduler/syscall/sys_getpgid.c b/src/kernel/scheduler/syscall/sys_getpgid.c new file mode 100644 index 0000000..a5221f2 --- /dev/null +++ b/src/kernel/scheduler/syscall/sys_getpgid.c @@ -0,0 +1,25 @@ +#include +#include +#include + +pid_t sys_getpgid(void) +{ + extern struct process *process_current; + pid_t ret; + + // Start artomic opetations + atomic_start(); + + // Check error + if (process_current == NULL) { + atomic_stop(); + return (-1); + } + + // Get Process Groupe ID + ret = process_current->pgid; + + // Stop atomic operation + atomic_stop(); + return (ret); +} diff --git a/src/kernel/scheduler/syscall/sys_getpid.c b/src/kernel/scheduler/syscall/sys_getpid.c new file mode 100644 index 0000000..0af1bdc --- /dev/null +++ b/src/kernel/scheduler/syscall/sys_getpid.c @@ -0,0 +1,25 @@ +#include +#include +#include + +pid_t sys_getpid(void) +{ + extern struct process *process_current; + pid_t ret; + + // Start artomic opetations + atomic_start(); + + // Check error + if (process_current == NULL) { + atomic_stop(); + return (-1); + } + + // Get Process ID + ret = process_current->pid; + + // Stop atomic operation + atomic_stop(); + return (ret); +} diff --git a/src/kernel/scheduler/syscall/sys_getppid.c b/src/kernel/scheduler/syscall/sys_getppid.c new file mode 100644 index 0000000..aa8e10f --- /dev/null +++ b/src/kernel/scheduler/syscall/sys_getppid.c @@ -0,0 +1,31 @@ +#include +#include +#include + +pid_t sys_getppid(void) +{ + extern struct process *process_current; + pid_t ret; + + // Start artomic opetations + atomic_start(); + + // Check error + if (process_current == NULL) { + atomic_stop(); + return (-1); + } + + // Check first process + if (process_current->parent == NULL) { + atomic_stop(); + return (0); + } + + // Get Parent Process ID + ret = process_current->parent->pid; + + // Stop atomic operation + atomic_stop(); + return (ret); +} diff --git a/src/kernel/scheduler/syscall/sys_setpgid.c b/src/kernel/scheduler/syscall/sys_setpgid.c new file mode 100644 index 0000000..6e46b1b --- /dev/null +++ b/src/kernel/scheduler/syscall/sys_setpgid.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int sys_setpgid(pid_t pid, pid_t pgid) +{ + extern struct process *process_current; + struct process *proc; + + // Start atomic operations + atomic_start(); + + // Get the appropriate process + proc = process_current; + if (pid != 0) + proc = process_get(pid); + + // Check error + if (proc == NULL) + return (-1); + + // Update Proocess Group ID + proc->pgid = (pgid == 0) ? process_current->pgid : pgid; + return (0); +} diff --git a/src/kernel/scheduler/syscall/sys_wait.c b/src/kernel/scheduler/syscall/sys_wait.c new file mode 100644 index 0000000..22666ba --- /dev/null +++ b/src/kernel/scheduler/syscall/sys_wait.c @@ -0,0 +1,6 @@ +#include + +pid_t sys_wait(int *wstatus) +{ + return (sys_waitpid(-1, wstatus, 0)); +} diff --git a/src/kernel/scheduler/syscall/sys_waitpid.c b/src/kernel/scheduler/syscall/sys_waitpid.c index 78df952..1866ac0 100644 --- a/src/kernel/scheduler/syscall/sys_waitpid.c +++ b/src/kernel/scheduler/syscall/sys_waitpid.c @@ -1,6 +1,78 @@ #include +#include +#include pid_t sys_waitpid(pid_t pid, int *wstatus, int options) { + extern struct process *process_current; + struct process **proc; + pid_t ret; + + + // Check useless wait + if (process_current->child == NULL) { + earlyterm_write("waitpid: no child\n"); + DBG_WAIT; + return (-1); + } + + //TODO: handle options + (void)options; + + // Wait util one of its children specified by PID + // has changed state + while (1) + { + // Start atomic operation + atomic_start(); + + // Find childs to check + proc = &process_current->child; + while (*proc != NULL) + { + // Check terminated child + if ((*proc)->status == PROC_ZOMBIE && + ((pid < -1 && (*proc)->pgid == -pid) || + pid == -1 || + (pid == 0 && (*proc)->pgid == process_current->pgid) || + (pid > 0 && (*proc)->pid == pid))) + { + // Change the child process state + (*proc)->status = PROC_DEAD; + + // Get the child process PID and stat_loc + ret = (*proc)->pid; + *wstatus = (*proc)->__stat_loc; + + // Remove process form the child list + *proc = (*proc)->sibling; + + //DEBUG + //earlyterm_write("waitpid: find %d\n", ret); + //DBG_WAIT; + //DBG_WAIT; + + // Stop atomic operation and return + atomic_stop(); + return (ret); + } + + // Get next child process + proc = &(*proc)->sibling; + } + + // Force process to sleep + // TODO: + // Schedule !! and change the niciess of the + // process !! + // + // Stop atomic operation and wait + atomic_stop(); + __asm__ volatile ("sleep; nop"); + } + + // Error + //earlyterm_write("waitpid: error\n"); + //DBG_WAIT; return (-1); } diff --git a/src/kernel/syscall/handler.c b/src/kernel/syscall/handler.c index a057a2b..e377dbc 100644 --- a/src/kernel/syscall/handler.c +++ b/src/kernel/syscall/handler.c @@ -1,4 +1,5 @@ #include +#include #include static void sys_test(uint32_t a, uint32_t b, uint32_t c, uint32_t d) @@ -12,7 +13,7 @@ static void sys_test(uint32_t a, uint32_t b, uint32_t c, uint32_t d) DBG_WAIT; } -static const void *sys_handler[9] = { +static const void *sys_handler[__NR_MAX] = { // Kernel Test sys_test, // test @@ -20,6 +21,11 @@ static const void *sys_handler[9] = { sys_exit, // exit sys_fexecve, // fexecve sys_waitpid, // waitpid + sys_wait, // wait + sys_getpid, // getpid + sys_getppid, // getppid + sys_getpgid, // getpgid + sys_setpgid, // setpgid // VFS sys_read, // read @@ -27,32 +33,18 @@ static const void *sys_handler[9] = { sys_open, // open sys_close, // close sys_lseek, // lseek - - // Display -/* kvram_display, // kvram_display - kvram_clear, // kvram_clear - printk, // printk - kvram_ascii, // kvram_ascii - kvram_reverse, // kvram_reverse - kvram_scroll, // kvram_scroll - kvram_clr_str_area // kvram_clr_str_area*/ }; void *sys_get_handler(int sysno) { // Check sysno validity - if (sysno < 0 || sysno >= 9) + if (sysno < 0 || sysno >= __NR_MAX) return (NULL); // DEBUG - /*kvram_clear(); - printk(0, 0, "TRAPA ABI pre_handler !"); - printk(0, 1, "sysno = %d", sysno); - printk(0, 2, "handler = %p", sys_handler[sysno]); - kvram_display(); - DBG_WAIT; - DBG_WAIT; - DBG_WAIT;*/ + //earlyterm_write("syscall (%d)!!\n", sysno); + //DBG_WAIT; + //DBG_WAIT; // Return syscall return ((void *)sys_handler[sysno]); diff --git a/src/lib/Makefile b/src/lib/Makefile index 15d928c..414517c 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -46,7 +46,7 @@ TARGET-LIBS-DYNAMIC := $(patsubst %,lib%_dyn.so,$(TARGET-MODULES)) #------- --------# all: $(TARGET-LIBS-STATIC) $(TARGET-LIBS-DYNAMIC) -$(BUILD-STATIC) $(BUILD-DYNAMIC): +$(BUILD-STATIC) $(BUILD-DYNAMIC) $(DEBUG-DYNLIB): @ printf "Create $(blue)$@$(nocolor) directory\n" @ mkdir -p $@ @@ -69,13 +69,13 @@ endef define rule-src-dynamic $(patsubst %,$(BUILD-DYNAMIC)/%.o,$(subst /,_,$(basename $1))): $1 | $(BUILD-DYNAMIC) @ printf "compiling $(white)$$<$(nocolor)..." - @ $(CC) -fPIC $(CFLAGS) -c $$< -o $$@ $(HEADER) + @ $(CC) -pie $(CFLAGS) -c $$< -o $$@ $(HEADER) @ printf "$(green)[ok]$(nocolor)\n" endef define rule-link-dynamic $(patsubst %,lib%_dyn.so,$1): $2 | $(DEBUG-DYNLIB) @ printf "Link $(green)$$@$(nocolor) lib\n" - $(CC) -shared -o $$@ $$^ -nostdlib -lgcc + $(CC) -T user_shared_lib.ld -Wl,-M -pie -o $$@ $$^ -nostdlib -lgcc > $(DEBUG-DYNLIB)/$$@.map endef diff --git a/src/lib/display/dupdate.S b/src/lib/display/dupdate.S index 329b975..27e0110 100644 --- a/src/lib/display/dupdate.S +++ b/src/lib/display/dupdate.S @@ -1,12 +1 @@ -#include -.text -.global _dupdate -.type _dupdate, @function - - -.align 2 -_dupdate: - trapa #__NR_kvram_display - rts - nop -.end +# TODO screen syscall handling :D diff --git a/src/lib/libc/unistd/fork.S b/src/lib/libc/unistd/fork.S deleted file mode 100644 index 59bc7df..0000000 --- a/src/lib/libc/unistd/fork.S +++ /dev/null @@ -1,13 +0,0 @@ -#include -.text -.global _fork -.type _fork, @function - - -.align 2 -_fork: - !trapa #__NR_fork - mov #-1, r0 - rts - nop -.end diff --git a/src/lib/libc/unistd/getpgid.S b/src/lib/libc/unistd/getpgid.S new file mode 100644 index 0000000..5b1b5bc --- /dev/null +++ b/src/lib/libc/unistd/getpgid.S @@ -0,0 +1,12 @@ +#include +.text +.global _getpgid +.type _getpgid, @function + + +.align 2 +_getpgid: + trapa #__NR_getpgid + rts + nop +.end diff --git a/src/lib/libc/unistd/getpid.S b/src/lib/libc/unistd/getpid.S new file mode 100644 index 0000000..d2e2146 --- /dev/null +++ b/src/lib/libc/unistd/getpid.S @@ -0,0 +1,12 @@ +#include +.text +.global _getpid +.type _getpid, @function + + +.align 2 +_getpid: + trapa #__NR_getpid + rts + nop +.end diff --git a/src/lib/libc/unistd/getppid.S b/src/lib/libc/unistd/getppid.S new file mode 100644 index 0000000..ca293d6 --- /dev/null +++ b/src/lib/libc/unistd/getppid.S @@ -0,0 +1,12 @@ +#include +.text +.global _getppid +.type _getppid, @function + + +.align 2 +_getppid: + trapa #__NR_getppid + rts + nop +.end diff --git a/src/lib/libc/unistd/setpgid.S b/src/lib/libc/unistd/setpgid.S new file mode 100644 index 0000000..6b8b82a --- /dev/null +++ b/src/lib/libc/unistd/setpgid.S @@ -0,0 +1,12 @@ +#include +.text +.global _setpgid +.type _setpgid, @function + + +.align 2 +_setpgid: + trapa #__NR_setpgid + rts + nop +.end diff --git a/src/user/shell/builtin/proc.c b/src/user/shell/builtin/proc.c index 0893c39..588aa33 100644 --- a/src/user/shell/builtin/proc.c +++ b/src/user/shell/builtin/proc.c @@ -9,21 +9,19 @@ int builtin_proc(void) int wstatus; puts("proc test entry :)\n"); - printf("printf test:\n"); - printf("0#10x: %0#10x\n", 0xabcdef); - printf("str: %s\n", "Oui le test oui ! :D"); - printf("interger: %d\n", 12345); - printf("interger: %lld\n", 999999999999999999); + 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"); if (child == -1) { - puts("fexecve fail :(\n"); + printf("fexecve fail :(\n"); return (0); } // Wait child death - waitpid(child, &wstatus, WUNTRACED); -*/ return (0); + waitpid(-1, &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 694d82c..4b6cbb3 100644 --- a/src/user/shell/main.c +++ b/src/user/shell/main.c @@ -7,35 +7,6 @@ int main(void) { char input[12]; int cmd_size; - //char **argv; - //int argc; - //int STDOUT_FILENO; - - // Try to open TTY - // @note: - // We use O_DIRECT to avoid cache - // generation because we do not have a - // lot of memory. - /*STDOUT_FILENO = open("/dev/tty", O_DIRECT); - if (STDOUT_FILENO < 0) - { - // Display error. - display_t disp; - dopen(&disp, "default"); - dclear(&disp); - dprint(&disp, 0, 0, "User program fail to open TTY"); - dprint(&disp, 0, 1, "Wait user manual reset..."); - dupdate(&disp); - - // Wait user manual reset. - while (1) - { - // @note: we can use "sleep" because we - // are in privilegied mode. - // TODO: use sleep syscall ! - __asm__ volatile ("sleep"); - } - }*/ // Shell main loop. write(STDOUT_FILENO, "Boot Complete !\n", 16); @@ -45,6 +16,10 @@ int main(void) write(STDOUT_FILENO, ">", 1); 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'; @@ -54,10 +29,7 @@ int main(void) { write(STDOUT_FILENO, input, cmd_size - 1); write(STDOUT_FILENO, ": command not found\n", 20); - } else { - write(STDOUT_FILENO, input, cmd_size - 1); - write(STDOUT_FILENO, ": command found :D !\n", 21); - } + } } return (0); } diff --git a/src/user/test/Makefile b/src/user/test/Makefile index d8d18cb..af7ec9e 100644 --- a/src/user/test/Makefile +++ b/src/user/test/Makefile @@ -9,7 +9,7 @@ include ../../../global.mk ## Static variables ##-- HEADER := -I../../../include -I../../../include/user -LIBS := -L../../lib/ -lunistd -lstdio -lstring -ldisplay -lgcc +LIBS := -L../../lib/ -llibc -ldisplay -lgcc BUILD := ../../../build/user/test DEBUG := ../../../debug_bin OUTPUT := ../../../output diff --git a/src/user/test/test.c b/src/user/test/test.c index 7425fa4..bda9a3f 100644 --- a/src/user/test/test.c +++ b/src/user/test/test.c @@ -1,19 +1,11 @@ -#include +#include +#include int main(void) { - uint32_t counter = 0; - while (1) - { - // Display data -// dclr_str_area(0, 2, 20, 1); -// dprint(0, 2, "C process: %d", counter); -// dupdate(); - - // Update counter and "wait" - counter = counter + 1; - if (counter >= 100) - counter = 0; - for (int i = 0 ; i < 300000 ; ++i); - } + setpgid(0, 12); + printf("%-6d%-6d%-6d\n", getppid(), getpid(), getpgid()); + printf("child proc fini...try to exit\n"); + for(int i = 0 ; i < 3000000 ; ++i); + return (84); } diff --git a/src/user/test/test_asm.s b/src/user/test/test_asm.s deleted file mode 100644 index ee21ea3..0000000 --- a/src/user/test/test_asm.s +++ /dev/null @@ -1,23 +0,0 @@ -/*.global _test -.type _test, @function - -.align 2 -_test: - sts.l pr, @-r15 - - mov.l .syscall_vram, r0 - mov.l .syscall_entry, r1 - jsr @r1 - nop - tst r0, r0 - bf _test - nop - - lds.l @r15+, pr - rts - nop - -.align 4 -.syscall_entry: .long 0xa0010070 -.syscall_vram: .long 0x00000135 -.end*/