From: <sam...@us...> - 2009-06-09 17:03:47
|
Revision: 366 http://aceos.svn.sourceforge.net/aceos/?rev=366&view=rev Author: samueldotj Date: 2009-06-09 17:03:41 +0000 (Tue, 09 Jun 2009) Log Message: ----------- Added initial code for devfs Added primitive code for syscalls Ported Bash 3.2.48 to Ace - still tty support is pending so you can execute a script but cant start it in interactive mode Modified CreateDevice() function to take extra parameters to create device nodes under /device Added KPRINTF macro - same as kprintf, it prints current function+line number also Did code refactoring for iom.c and split the functionality into 3 separate files - driver.c, irp.c and iom.c Added extra fields in Task structure to store commandline, environment variables for a task. Fixed a bug in CopyVirtualAddressRange function - now src_size can be smaller than dest_size the remaining bytes will be zero filled. Fixed a bug in a scheduler - a hang condition is now avoided - PreemptThread will be called even if current_thread==new_therad, but nothing will be done in PreemptThread Modified Paths: -------------- src/drivers/acpi/acpi.c src/drivers/pci/pci.c src/drivers/ps2keyboard/keyboard.c src/include/kernel/debug.h src/include/kernel/iom/iom.h src/include/kernel/ipc.h src/include/kernel/mm/vm.h src/include/kernel/pm/task.h src/include/kernel/vfs/vfs.h src/kernel/i386/arch.c src/kernel/i386/pm/thread.c src/kernel/iom/iom.c src/kernel/iom/rootbus.c src/kernel/ipc/message_queue.c src/kernel/ktrace.c src/kernel/main.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/mm/vm_unit.c src/kernel/pm/elf.c src/kernel/pm/scheduler.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/vfs/boot_fs.c src/kernel/vfs/vfs.c src/kernel/vfs/vnode.c src/kernel/wscript_build toolchain/newlib-1.17.0.patch Added Paths: ----------- src/include/kernel/iom/devfs.h src/include/libc/ src/include/libc/sys/ src/include/libc/sys/errno.h src/include/libc/sys/fcntl.h src/include/libc/sys/stat.h src/include/libc/sys/types.h src/include/libc/sys/utsname.h src/kernel/iom/devfs.c src/kernel/iom/driver.c src/kernel/iom/irp.c src/kernel/syscall/ src/kernel/syscall/entry.c src/kernel/syscall/file.c src/kernel/syscall/memory.c src/kernel/syscall/mount.c src/kernel/syscall/process.c src/kernel/syscall/scheduler.c src/kernel/syscall/signal.c src/kernel/syscall/statfs.c src/kernel/syscall/sys.c src/kernel/syscall/terminal.c src/kernel/syscall/time.c src/kernel/syscall/uname.c toolchain/bash-3.2.48.patch Removed Paths: ------------- src/kernel/system_calls.c Modified: src/drivers/acpi/acpi.c =================================================================== --- src/drivers/acpi/acpi.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/drivers/acpi/acpi.c 2009-06-09 17:03:41 UTC (rev 366) @@ -28,7 +28,7 @@ { DEVICE_OBJECT_PTR device_object; ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object); + err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object, NULL); if( err != ERROR_SUCCESS ) return err; InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -67,7 +67,7 @@ if ( ret == AE_OK && dev_info_ptr->Valid & ACPI_VALID_HID ) { DEVICE_OBJECT_PTR child_device_object; - if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) + if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object, NULL) == ERROR_SUCCESS ) { ACPI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; device_ext->handle = ObjHandle; Modified: src/drivers/pci/pci.c =================================================================== --- src/drivers/pci/pci.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/drivers/pci/pci.c 2009-06-09 17:03:41 UTC (rev 366) @@ -17,8 +17,8 @@ #define MAX_PCI_FUNCTION_PER_DEVICE 8 #if ARCH==i386 - #define PCI_CONFIG_ADDRESS 0xCF8 - #define PCI_CONFIG_DATA 0xCFC + #define PCI_CONFIG_ADDRESS 0xCF8 + #define PCI_CONFIG_DATA 0xCFC #endif typedef struct pci_bus_device_extension PCI_BUS_DEVICE_EXTENSION, * PCI_BUS_DEVICE_EXTENSION_PTR; @@ -98,7 +98,7 @@ { DEVICE_OBJECT_PTR device_object; ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object); + err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object, NULL); if( err != ERROR_SUCCESS ) return err; InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -134,7 +134,7 @@ char *class_name, *subclass_name, *prog_if_name; get_pci_class_string(pci_conf.base_class_code, pci_conf.sub_class_code, pci_conf.programming_interface, &class_name, &subclass_name, &prog_if_name ); //kprintf("%x %x %s %s %s\n", pci_conf.vendor_id, pci_conf.device_id, class_name, subclass_name, prog_if_name ); - if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) + if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object, NULL) == ERROR_SUCCESS ) { PCI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; memcpy(&device_ext->pci_conf, &pci_conf, sizeof(PCI_CONFIGURATION_SPACE) ); Modified: src/drivers/ps2keyboard/keyboard.c =================================================================== --- src/drivers/ps2keyboard/keyboard.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/drivers/ps2keyboard/keyboard.c 2009-06-09 17:03:41 UTC (rev 366) @@ -142,7 +142,7 @@ DEVICE_OBJECT_PTR dev_obj; ERROR_CODE err; - err = CreateDevice(drv_obj, 0, &dev_obj); + err = CreateDevice(drv_obj, 0, &dev_obj, NULL); if( err != ERROR_SUCCESS ) return err; Modified: src/include/kernel/debug.h =================================================================== --- src/include/kernel/debug.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/debug.h 2009-06-09 17:03:41 UTC (rev 366) @@ -23,6 +23,9 @@ #define KTRACE( ... ) #endif +#define KPRINTF( ... ) \ + kprintf("%s:%d: ", __PRETTY_FUNCTION__ , __LINE__ ); \ + kprintf( __VA_ARGS__ ); #ifdef __cplusplus extern "C" { Added: src/include/kernel/iom/devfs.h =================================================================== --- src/include/kernel/iom/devfs.h (rev 0) +++ src/include/kernel/iom/devfs.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,39 @@ +/*! \file kernel/iom/devfs.h + \brief devfs metadata structures +*/ + +#ifndef DEVFS_H +#define DEVFS_H + +#include <ace.h> +#include <ds/avl_tree.h> +#include <ds/list.h> +#include <ds/lrulist.h> +#include <heap/slab_allocator.h> + +/*! maximum length of a special file*/ +#define DEVFS_FILE_NAME_MAX 50 + +/*! a special file's directory entry*/ +typedef struct devfs_metadata +{ + char name[DEVFS_FILE_NAME_MAX]; /*! name of the special file */ + DEVICE_OBJECT_PTR device; /*! device associated with the file*/ + + AVL_TREE tree; /*! tree of files*/ +}DEVFS_METADATA, * DEVFS_METADATA_PTR; + +extern AVL_TREE_PTR devfs_root; + +#ifdef __cplusplus + extern "C" { +#endif + +ERROR_CODE CreateDeviceNode(const char * filename, DEVICE_OBJECT_PTR device); + +#ifdef __cplusplus + } +#endif + +#endif + Modified: src/include/kernel/iom/iom.h =================================================================== --- src/include/kernel/iom/iom.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/iom/iom.h 2009-06-09 17:03:41 UTC (rev 366) @@ -14,8 +14,10 @@ #include <kernel/mm/kmem.h> #include <kernel/vfs/vfs.h> +/*! maximum characters in driver name including spaces*/ #define DRIVER_NAME_MAX 50 +/*! total size in bytes to hold given number of device's device relation object*/ #define SIZEOF_DEVICE_RELATIONS(number_of_pdos) (sizeof(DEVICE_RELATIONS) + ((number_of_pdos) * sizeof(DEVICE_OBJECT)) ) typedef enum @@ -220,7 +222,6 @@ DEVICE_OBJECT_PTR objects[0]; }; - extern DEVICE_OBJECT_PTR root_bus_device_object; extern DRIVER_OBJECT_PTR root_bus_driver_object; @@ -228,17 +229,21 @@ extern CACHE device_object_cache; void InitIoManager(); -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object); + +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name); DEVICE_OBJECT_PTR AttachDeviceToDeviceStack(DEVICE_OBJECT_PTR source_device, DEVICE_OBJECT_PTR target_device); +void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type); + IO_STACK_LOCATION_PTR GetNextIrpStackLocation(IRP_PTR Irp); IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp); -void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type); +inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context); + IRP_PTR AllocateIrp(BYTE stack_size); void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code); void FreeIrp(IRP_PTR irp); ERROR_CODE CallDriver(DEVICE_OBJECT_PTR device_object, IRP_PTR irp); -inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context); DRIVER_OBJECT_PTR LoadRootBusDriver(); ERROR_CODE RootBusDriverEntry(DRIVER_OBJECT_PTR pDriverObject); + #endif Modified: src/include/kernel/ipc.h =================================================================== --- src/include/kernel/ipc.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/ipc.h 2009-06-09 17:03:41 UTC (rev 366) @@ -23,7 +23,7 @@ MESSAGE_TYPE_REFERENCE, MESSAGE_TYPE_SHARE, MESSAGE_TYPE_SHARE_PA -}MESSAGE_TYPE; +}MESSAGE_TYPE, * MESSAGE_TYPE_PTR; typedef enum { @@ -36,15 +36,19 @@ IPC_ARG_COUNT }IPC_ARG_INDEX; -#define IPC_ARG_ADDRESS IPC_ARG_INDEX_5 -#define IPC_ARG_LENGTH IPC_ARG_INDEX_6 +/*! index of address argument in the IPC message*/ +#define IPC_ADDRESS_ARG_INDEX IPC_ARG_INDEX_5 +/*! index of length argument in the IPC message*/ +#define IPC_LENGTH_ARG_INDEX IPC_ARG_INDEX_6 -#define ipc_arg_address ((void *)arg5) -#define ipc_arg_length ((long)arg6) +/*! alias for IPC address argument*/ +#define IPR_ARGUMENT_ADDRESS ((void *)arg5) +/*! alias for IPC length argument*/ +#define IPC_ARGUMENT_LENGTH ((long)arg6) typedef void * IPC_ARG_TYPE; +typedef IPC_ARG_TYPE * IPC_ARG_TYPE_PTR; - typedef struct message_buffer { LIST message_buffer_queue; /*! link list of message buffers in this message queue*/ Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/mm/vm.h 2009-06-09 17:03:41 UTC (rev 366) @@ -211,7 +211,7 @@ ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size, UINT32 flags); ERROR_CODE MapViewOfFile(int file_id, VADDR * va, UINT32 protection, UINT32 file_offset, UINT32 size, UINT32 preferred_start, UINT32 flags); -ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); +ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size); Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/pm/task.h 2009-06-09 17:03:41 UTC (rev 366) @@ -37,7 +37,15 @@ MESSAGE_QUEUE message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to message queue containing IPC messages */ - PROCESS_FILE_INFO process_file_info; + PROCESS_FILE_INFO process_file_info; /*! open file info */ + + char * kva_command_line; /*! kernel virtual address of command line*/ + char * uva_command_line; /*! user virtual address of command line - once user va is created kva will be freed*/ + + char * kva_environment; /*! kernel virtual address of process environment*/ + char * uva_environment; /*! user virtual address of environment - once user va is created kva will be freed*/ + + char * user_scratch; /*! temporary memory to copy kernel content to user*/ }; extern CACHE task_cache; @@ -51,7 +59,7 @@ int TaskCacheDestructor(void * buffer); void InitKernelTask(); -TASK_PTR CreateTask(char * exe_file_path); +TASK_PTR CreateTask(char * exe_file_path, char * command_line, char * environment); inline TASK_PTR GetCurrentTask(); TASK_PTR PidToTask(int pid); Modified: src/include/kernel/vfs/vfs.h =================================================================== --- src/include/kernel/vfs/vfs.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/vfs/vfs.h 2009-06-09 17:03:41 UTC (rev 366) @@ -224,6 +224,8 @@ ERROR_CODE OpenFile(char * file_path, VFS_ACCESS_TYPE access, VFS_OPEN_FLAG open_flag, int * file_id); ERROR_CODE CloseFile(int file_id); +ERROR_CODE GetVfsMessage(MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time, MESSAGE_TYPE_PTR type, IPC_ARG_TYPE_PTR arg1, IPC_ARG_TYPE_PTR arg2, IPC_ARG_TYPE_PTR arg3, IPC_ARG_TYPE_PTR arg4, IPC_ARG_TYPE_PTR arg5, IPC_ARG_TYPE_PTR arg6); + #ifdef __cplusplus } #endif Added: src/include/libc/sys/errno.h =================================================================== --- src/include/libc/sys/errno.h (rev 0) +++ src/include/libc/sys/errno.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,131 @@ +/*! User mode error numbers*/ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +#define EPERM 1 /* Not super-user */ +#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 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No children */ +#define EAGAIN 11 /* No more processes */ +#define ENOMEM 12 /* Not enough core */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Mount device 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 /* Too many open files in system */ +#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 arg out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define ENOMSG 35 /* No message of desired type */ +#define EIDRM 36 /* Identifier removed */ +#define ECHRNG 37 /* Channel number out of range */ +#define EL2NSYNC 38 /* Level 2 not synchronized */ +#define EL3HLT 39 /* Level 3 halted */ +#define EL3RST 40 /* Level 3 reset */ +#define ELNRNG 41 /* Link number out of range */ +#define EUNATCH 42 /* Protocol driver not attached */ +#define ENOCSI 43 /* No CSI structure available */ +#define EL2HLT 44 /* Level 2 halted */ +#define EDEADLK 45 /* Deadlock condition */ +#define ENOLCK 46 /* No record locks available */ +#define EBADE 50 /* Invalid exchange */ +#define EBADR 51 /* Invalid request descriptor */ +#define EXFULL 52 /* Exchange full */ +#define ENOANO 53 /* No anode */ +#define EBADRQC 54 /* Invalid request code */ +#define EBADSLT 55 /* Invalid slot */ +#define EDEADLOCK 56 /* File locking deadlock error */ +#define EBFONT 57 /* Bad font file fmt */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data (for no delay io) */ +#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 /* The object is remote */ +#define ENOLINK 67 /* The 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 74 /* Multihop attempted */ +#define ELBIN 75 /* Inode is remote (not really error) */ +#define EDOTDOT 76 /* Cross mount point (not really error) */ +#define EBADMSG 77 /* Trying to read unreadable message */ +#define EFTYPE 79 /* Inappropriate file type or format */ +#define ENOTUNIQ 80 /* Given log. name not unique */ +#define EBADFD 81 /* f.d. invalid for this operation */ +#define EREMCHG 82 /* Remote address changed */ +#define ELIBACC 83 /* Can't access a needed shared lib */ +#define ELIBBAD 84 /* Accessing a corrupted shared lib */ +#define ELIBSCN 85 /* .lib section in a.out corrupted */ +#define ELIBMAX 86 /* Attempting to link in too many libs */ +#define ELIBEXEC 87 /* Attempting to exec a shared library */ +#define ENOSYS 88 /* Function not implemented */ +#define ENMFILE 89 /* No more files */ +#define ENOTEMPTY 90 /* Directory not empty */ +#define ENAMETOOLONG 91 /* File or path name too long */ +#define ELOOP 92 /* Too many symbolic links */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */ +#define EPROTOTYPE 107 /* Protocol wrong type for socket */ +#define ENOTSOCK 108 /* Socket operation on non-socket */ +#define ENOPROTOOPT 109 /* Protocol not available */ +#define ESHUTDOWN 110 /* Can't send after socket shutdown */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EADDRINUSE 112 /* Address already in use */ +#define ECONNABORTED 113 /* Connection aborted */ +#define ENETUNREACH 114 /* Network is unreachable */ +#define ENETDOWN 115 /* Network interface is not configured */ +#define ETIMEDOUT 116 /* Connection timed out */ +#define EHOSTDOWN 117 /* Host is down */ +#define EHOSTUNREACH 118 /* Host is unreachable */ +#define EINPROGRESS 119 /* Connection already in progress */ +#define EALREADY 120 /* Socket already connected */ +#define EDESTADDRREQ 121 /* Destination address required */ +#define EMSGSIZE 122 /* Message too long */ +#define EPROTONOSUPPORT 123 /* Unknown protocol */ +#define ESOCKTNOSUPPORT 124 /* Socket type not supported */ +#define EADDRNOTAVAIL 125 /* Address not available */ +#define ENETRESET 126 +#define EISCONN 127 /* Socket is already connected */ +#define ENOTCONN 128 /* Socket is not connected */ +#define ETOOMANYREFS 129 +#define EPROCLIM 130 +#define EUSERS 131 +#define EDQUOT 132 +#define ESTALE 133 +#define ENOTSUP 134 /* Not supported */ +#define ENOMEDIUM 135 /* No medium (in tape drive) */ +#define ENOSHARE 136 /* No such host or network path */ +#define ECASECLASH 137 /* Filename exists with different case */ +#define EILSEQ 138 +#define EOVERFLOW 139 /* Value too large for defined data type */ +#define ECANCELED 140 /* Operation canceled */ +#define ENOTRECOVERABLE 141 /* State not recoverable */ +#define EOWNERDEAD 142 /* Previous owner died */ + +#endif Added: src/include/libc/sys/fcntl.h =================================================================== --- src/include/libc/sys/fcntl.h (rev 0) +++ src/include/libc/sys/fcntl.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,157 @@ +#ifndef _SYS_FCNTL_H_ +#define _SYS_FCNTL_H_ + +#define _FOPEN (-1) /* from sys/file.h, kernel use only */ +#define _FREAD 0x0001 /* read enabled */ +#define _FWRITE 0x0002 /* write enabled */ +#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */ +#define _FMARK 0x0010 /* internal; mark during gc() */ +#define _FDEFER 0x0020 /* internal; defer for next gc pass */ +#define _FASYNC 0x0040 /* signal pgrp when data ready */ +#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */ +#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */ +#define _FCREAT 0x0200 /* open with file create */ +#define _FTRUNC 0x0400 /* open with truncation */ +#define _FEXCL 0x0800 /* error on open if file exists */ +#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */ +#define _FSYNC 0x2000 /* do all writes synchronously */ +#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */ +#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */ +#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */ + +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* + * Flag values for open(2) and fcntl(2) + * The kernel adds 1 to the open modes to turn it into some + * combination of FREAD and FWRITE. + */ +#define O_RDONLY 0 /* +1 == FREAD */ +#define O_WRONLY 1 /* +1 == FWRITE */ +#define O_RDWR 2 /* +1 == FREAD|FWRITE */ +#define O_APPEND _FAPPEND +#define O_CREAT _FCREAT +#define O_TRUNC _FTRUNC +#define O_EXCL _FEXCL +#define O_SYNC _FSYNC +/* O_NDELAY _FNDELAY set in include/fcntl.h */ +/* O_NDELAY _FNBIO set in include/fcntl.h */ +#define O_NONBLOCK _FNONBLOCK +#define O_NOCTTY _FNOCTTY +/* For machines which care - */ +#if defined (_WIN32) || defined (__CYGWIN__) +#define _FBINARY 0x10000 +#define _FTEXT 0x20000 +#define _FNOINHERIT 0x40000 + +#define O_BINARY _FBINARY +#define O_TEXT _FTEXT +#define O_NOINHERIT _FNOINHERIT + +/* The windows header files define versions with a leading underscore. */ +#define _O_RDONLY O_RDONLY +#define _O_WRONLY O_WRONLY +#define _O_RDWR O_RDWR +#define _O_APPEND O_APPEND +#define _O_CREAT O_CREAT +#define _O_TRUNC O_TRUNC +#define _O_EXCL O_EXCL +#define _O_TEXT O_TEXT +#define _O_BINARY O_BINARY +#define _O_RAW O_BINARY +#define _O_NOINHERIT O_NOINHERIT +#endif + +#ifndef _POSIX_SOURCE + +/* + * Flags that work for fcntl(fd, F_SETFL, FXXXX) + */ +#define FAPPEND _FAPPEND +#define FSYNC _FSYNC +#define FASYNC _FASYNC +#define FNBIO _FNBIO +#define FNONBIO _FNONBLOCK /* XXX fix to be NONBLOCK everywhere */ +#define FNDELAY _FNDELAY + +/* + * Flags that are disallowed for fcntl's (FCNTLCANT); + * used for opens, internal state, or locking. + */ +#define FREAD _FREAD +#define FWRITE _FWRITE +#define FMARK _FMARK +#define FDEFER _FDEFER +#define FSHLOCK _FSHLOCK +#define FEXLOCK _FEXLOCK + +/* + * The rest of the flags, used only for opens + */ +#define FOPEN _FOPEN +#define FCREAT _FCREAT +#define FTRUNC _FTRUNC +#define FEXCL _FEXCL +#define FNOCTTY _FNOCTTY + +#endif /* !_POSIX_SOURCE */ + +/* XXX close on exec request; must match UF_EXCLOSE in user.h */ +#define FD_CLOEXEC 1 /* posix */ + +/* fcntl(2) requests */ +#define F_DUPFD 0 /* Duplicate fildes */ +#define F_GETFD 1 /* Get fildes flags (close on exec) */ +#define F_SETFD 2 /* Set fildes flags (close on exec) */ +#define F_GETFL 3 /* Get file flags */ +#define F_SETFL 4 /* Set file flags */ +#ifndef _POSIX_SOURCE +#define F_GETOWN 5 /* Get owner - for ASYNC */ +#define F_SETOWN 6 /* Set owner - for ASYNC */ +#endif /* !_POSIX_SOURCE */ +#define F_GETLK 7 /* Get record-locking information */ +#define F_SETLK 8 /* Set or Clear a record-lock (Non-Blocking) */ +#define F_SETLKW 9 /* Set or Clear a record-lock (Blocking) */ +#ifndef _POSIX_SOURCE +#define F_RGETLK 10 /* Test a remote lock to see if it is blocked */ +#define F_RSETLK 11 /* Set or unlock a remote lock */ +#define F_CNVT 12 /* Convert a fhandle to an open fd */ +#define F_RSETLKW 13 /* Set or Clear remote record-lock(Blocking) */ +#endif /* !_POSIX_SOURCE */ + +/* fcntl(2) flags (l_type field of flock structure) */ +#define F_RDLCK 1 /* read lock */ +#define F_WRLCK 2 /* write lock */ +#define F_UNLCK 3 /* remove lock(s) */ +#ifndef _POSIX_SOURCE +#define F_UNLKSYS 4 /* remove remote locks for a given system */ +#endif /* !_POSIX_SOURCE */ + +/*#include <sys/stdtypes.h>*/ + +/* file segment locking set data type - information passed to system by user */ +struct flock { + short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ + short l_whence; /* flag to choose starting offset */ + long l_start; /* relative offset, in bytes */ + long l_len; /* length, in bytes; 0 means lock to EOF */ + short l_pid; /* returned with F_GETLK */ + short l_xxx; /* reserved for future use */ +}; + +#ifndef _POSIX_SOURCE +/* extended file segment locking set data type */ +struct eflock { + short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ + short l_whence; /* flag to choose starting offset */ + long l_start; /* relative offset, in bytes */ + long l_len; /* length, in bytes; 0 means lock to EOF */ + short l_pid; /* returned with F_GETLK */ + short l_xxx; /* reserved for future use */ + long l_rpid; /* Remote process id wanting this lock */ + long l_rsys; /* Remote system id wanting this lock */ +}; +#endif /* !_POSIX_SOURCE */ + + +#endif Added: src/include/libc/sys/stat.h =================================================================== --- src/include/libc/sys/stat.h (rev 0) +++ src/include/libc/sys/stat.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,72 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include <sys/types.h> + +struct stat +{ + dev_t st_dev; /*Device ID of device containing file. */ + ino_t st_ino; /*File serial number. */ + mode_t st_mode; /*Mode of file */ + nlink_t st_nlink; /*Number of hard links to the file. */ + uid_t st_uid; /*User ID of file. */ + gid_t st_gid; /*Group ID of file. */ + + dev_t st_rdev; /*Device ID (if file is character or block special). */ + + off_t st_size; /*For regular files, the file size in bytes. + For symbolic links, the length in bytes of the pathname contained in the symbolic link. + For a shared memory object, the length in bytes. + For a typed memory object, the length in bytes. + For other file types, the use of this field is unspecified. */ + time_t st_atime; /*Time of last access. */ + time_t st_mtime; /*Time of last data modification. */ + time_t st_ctime; /*Time of last status change. */ + + blksize_t st_blksize; /*A file system-specific preferred I/O block size for this object. In some file system types, this may vary from file to file.*/ + blkcnt_t st_blocks; /*Number of blocks allocated for this object.*/ +}; + +/* Traditional mask definitions for st_mode. */ +#define S_IFMT 0170000 /* type of file */ +#define S_IFLNK 0120000 /* symbolic link */ +#define S_IFREG 0100000 /* regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFIFO 0010000 /* this is a FIFO */ +#define S_ISUID 0004000 /* set user id on execution */ +#define S_ISGID 0002000 /* set group id on execution */ + /* next is reserved for future use */ +#define S_ISVTX 01000 /* save swapped text even after use */ + +/* POSIX masks for st_mode. */ +#define S_IRWXU 00700 /* owner: rwx------ */ +#define S_IRUSR 00400 /* owner: r-------- */ +#define S_IWUSR 00200 /* owner: -w------- */ +#define S_IXUSR 00100 /* owner: --x------ */ + +#define S_IRWXG 00070 /* group: ---rwx--- */ +#define S_IRGRP 00040 /* group: ---r----- */ +#define S_IWGRP 00020 /* group: ----w---- */ +#define S_IXGRP 00010 /* group: -----x--- */ + +#define S_IRWXO 00007 /* others: ------rwx */ +#define S_IROTH 00004 /* others: ------r-- */ +#define S_IWOTH 00002 /* others: -------w- */ +#define S_IXOTH 00001 /* others: --------x */ + +/* Synonyms for above. */ +#define S_IEXEC S_IXUSR +#define S_IWRITE S_IWUSR +#define S_IREAD S_IRUSR + +/* The following macros test st_mode (from POSIX Sec. 5.6.1.1). */ +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) /* is a reg file */ +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* is a directory */ +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) /* is a char spec */ +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) /* is a block spec */ +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) /* is a symlink */ +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* is a pipe/FIFO */ + +#endif Added: src/include/libc/sys/types.h =================================================================== --- src/include/libc/sys/types.h (rev 0) +++ src/include/libc/sys/types.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,117 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +#if !defined(__time_t_defined) && !defined(_TIME_T) +#define _TIME_T +#define __time_t_defined +typedef _TIME_T_ time_t; +#endif + +#if !defined(__clock_t_defined) && !defined(_CLOCK_T) +#define _CLOCK_T +#define __clock_t_defined +typedef _CLOCK_T_ clock_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef _ssize_t ssize_t; +#endif + +#ifndef __u_char_defined +#ifdef __GNUC__ +__extension__ typedef long long quad_t; +__extension__ typedef unsigned long long u_quad_t; +#else +typedef struct +{ + long int __val[2]; +} quad_t; +typedef struct +{ + unsigned long __val[2]; +} u_quad_t; +#endif +typedef struct +{ + int __val[2]; +} fsid_t; +#define __u_char_defined +#endif + +typedef int clockid_t; + +# define _SYS_TYPES_FD_SET +# define NBBY 8 /* number of bits in a byte */ +/* + * Select uses bit masks of file descriptors in longs. + * These macros manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here + * should be >= NOFILE (param.h). + */ +# ifndef FD_SETSIZE +# define FD_SETSIZE 64 +# endif + +typedef long fd_mask; +# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */ +# ifndef howmany +# define howmany(x,y) (((x)+((y)-1))/(y)) +# endif + +typedef struct { + unsigned long fds_bits [(1024/(8 * sizeof(unsigned long)))]; +} __fd_set; + +typedef __fd_set fd_set; + +# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS))) +# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS))) +# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS))) +# define FD_ZERO(p) (__extension__ (void)({ \ + size_t __i; \ + char *__tmp = (char *)p; \ + for (__i = 0; __i < sizeof (*(p)); ++__i) \ + *__tmp++ = 0; \ +})) + +#define __mode_t_defined +#define __gid_t_defined +#define __uid_t_defined +#define __pid_t_defined +#define __ssize_t_defined +#define __key_t_defined +#define __off_t_defined +#define __off64_t_defined + +typedef int dev_t; +typedef int ino_t; +typedef int mode_t; +typedef int caddr_t; +typedef long off_t; +typedef int pid_t; +typedef int uid_t; +typedef int gid_t; +typedef int key_t; +typedef int nlink_t; +typedef long suseconds_t; +typedef long useconds_t; + +typedef long blksize_t; +typedef long blkcnt_t; + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned char u_int8_t; +typedef unsigned short u_int16_t; +typedef unsigned long u_int32_t; +typedef unsigned long long u_int64_t; + +typedef u_int32_t __uint32_t; +typedef int32_t __int32_t; +typedef u_int16_t __uint16_t; +typedef int16_t __int16_t; + +#endif Added: src/include/libc/sys/utsname.h =================================================================== --- src/include/libc/sys/utsname.h (rev 0) +++ src/include/libc/sys/utsname.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,23 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#include <ace.h> + +#define UTS_MAX_NAME 50 + +#define UTS_SYSTEM_NAME "Ace" +#define UTS_NODE_NAME "Ace Node" +#define UTS_RELEASE "I" +#define UTS_VERSION "3" +#define UTS_MACHINE "ARCH" + + +struct utsname { + char sysname[UTS_MAX_NAME]; /*! name of this implementation of the operating system*/ + char nodename[UTS_MAX_NAME]; /*! name of this node within an implementation-dependent communications network*/ + char release[UTS_MAX_NAME]; /*! current release level of this implementation*/ + char version[UTS_MAX_NAME]; /*! current version level of this release*/ + char machine[UTS_MAX_NAME]; /*! name of the hardware type on which the system is running*/ +}; + +#endif Modified: src/kernel/i386/arch.c =================================================================== --- src/kernel/i386/arch.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/kernel/i386/arch.c 2009-06-09 17:03:41 UTC (rev 366) @@ -121,7 +121,7 @@ /* Initialize real time clock*/ InitRtc(); - + /*setup double fault handler tss and gdt entries*/ FillTssForDoubleFaultHandler(DoubleFaultHandler); Modified: src/kernel/i386/pm/thread.c =================================================================== --- src/kernel/i386/pm/thread.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/kernel/i386/pm/thread.c 2009-06-09 17:03:41 UTC (rev 366) @@ -56,7 +56,7 @@ { regs->cs = USER_CODE_SELECTOR | USER_PRIVILEGE_LEVEL; regs->ds = regs->es = regs->gs = regs->fs = regs->ss = USER_DATA_SELECTOR | USER_PRIVILEGE_LEVEL; - regs->useresp = user_stack; + regs->useresp = user_stack + USER_STACK_SIZE; /*stack grows from top to bottom*/ } regs->eip = (UINT32)start_address; Added: src/kernel/iom/devfs.c =================================================================== --- src/kernel/iom/devfs.c (rev 0) +++ src/kernel/iom/devfs.c 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,309 @@ +/*! + \file kernel/iom/devfs.c + \brief Device File system interface - /device +*/ + +#include <ace.h> +#include <string.h> +#include <tar.h> +#include <ds/lrulist.h> +#include <ds/avl_tree.h> +#include <sync/spinlock.h> +#include <kernel/debug.h> +#include <kernel/ipc.h> +#include <kernel/iom/iom.h> +#include <kernel/iom/devfs.h> +#include <kernel/pm/pm_types.h> +#include <kernel/pm/thread.h> +#include <kernel/pm/scheduler.h> +#include <kernel/vfs/vfs.h> + +/*! User friendly name of the device fs*/ +#define DEV_FS_NAME "device fs" +/*! virtual device name*/ +#define DEV_FS_MOUNT_DEVICE "dev_device" +/*! Where to mount device fs*/ +#define DEV_FS_MOUNT_PATH "/device" + +#define DEV_FS_TIME_OUT 5 + +/*! messages passed to device fs is queued up here - It will be processed by device fs thread*/ +MESSAGE_QUEUE device_fs_message_queue; + +/*! root of devfs*/ +AVL_TREE_PTR devfs_root=NULL; + +/*! total device files*/ +static int devfs_total_directory_entries=0; + +/*! cache for devfs metadata*/ +CACHE devfs_cache; + +#define DEVFS_CACHE_FREE_SLABS_THRESHOLD 10 +#define DEVFS_CACHE_MIN_BUFFERS 20 +#define DEVFS_CACHE_MAX_SLABS 30 + +/*! used as argument to avl tree enumerate function of dev node tree*/ +typedef struct devfs_direntry_param +{ + FILE_STAT_PARAM_PTR file_stat; /*! starting address of file_stat param array*/ + int current_index; /*! current index into file_stat param array*/ + int max_entries; /*! max entries in the file_stat param*/ + + int result; /*! result of the enum operation*/ +}DEVFS_DIRENTRY_PARAM, * DEVFS_DIRENTRY_PARAM_PTR; + +static void DevFsMessageReceiver(); +static void ProcessVfsMessage( MESSAGE_TYPE message_type, VFS_IPC vfs_id, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6 ); +static FILE_STAT_PARAM_PTR GetDirectoryEntries(void * fs_data, int inode, char * file_name, int max_entries, int * total_entries); +int enumerate_devfs_tree_callback(AVL_TREE_PTR node, void * arg); + +static COMPARISION_RESULT compare_dev_node_name(struct binary_tree * node1, struct binary_tree * node2); +int DevFsCacheConstructor( void *buffer); +int DevFsCacheDestructor( void *buffer); + +/*! Registers the device file system and mounts /device mount point +*/ +void InitDevFs() +{ + ERROR_CODE ret; + + /*initialize cache object of devfs*/ + if( InitCache(&devfs_cache, sizeof(DEVFS_METADATA), DEVFS_CACHE_FREE_SLABS_THRESHOLD, DEVFS_CACHE_MIN_BUFFERS, DEVFS_CACHE_MAX_SLABS, DevFsCacheConstructor, DevFsCacheDestructor) ) + panic("InitDevFs - cache init failed"); + + InitMessageQueue( &device_fs_message_queue ); + + /*Create a receiver thread*/ + CreateThread( &kernel_task, DevFsMessageReceiver, SCHED_CLASS_HIGH, TRUE ); + + /*register device file system*/ + ret = RegisterFileSystem( DEV_FS_NAME, &device_fs_message_queue ); + if ( ret != ERROR_SUCCESS ) + { + KPRINTF("%s\n", ERROR_CODE_AS_STRING(ret) ); + panic( "devfs registeration failed" ); + } + /*mount boot fs on a virtual device*/ + ret = MountFileSystem( DEV_FS_NAME, DEV_FS_MOUNT_DEVICE, DEV_FS_MOUNT_PATH ); + if ( ret != ERROR_SUCCESS ) + { + KPRINTF("%s\n", ERROR_CODE_AS_STRING(ret) ); + panic( "devfs mount failed" ); + } +} + +/*! DevFs thread + * Processes VFS requests from VFS server and fulfills the requests + */ +static void DevFsMessageReceiver() +{ + ERROR_CODE err; + MESSAGE_TYPE type; + IPC_ARG_TYPE arg1, arg2, arg3, arg4, arg5, arg6; + + while ( 1 ) + { + err = GetVfsMessage(&device_fs_message_queue, DEV_FS_TIME_OUT, &type, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); + if ( err == ERROR_SUCCESS ) + ProcessVfsMessage( type, (VFS_IPC)arg1, arg2, arg3, arg4, arg5, arg6 ); + else + kprintf( "devfs IPC message receive error : %d\n", err ); + + /*!\todo - process unregister/shutdown request and exit this thread*/ + } + kprintf( "Exiting devfs\n" ); +} + +/*! Processes a VFS message and take neccessary action(reply to the VFS) + * \param message_type - message queue message type - value/reference/shared etc + * \param vfs_id - VFS message type - mount/unmount/read/write etc + * \param arg2-6 - Arguments to the message + * */ +static void ProcessVfsMessage( MESSAGE_TYPE message_type, VFS_IPC vfs_id, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6 ) +{ + FILE_STAT_PARAM_PTR de; + int total_entries=0; + DIRECTORY_ENTRY_PARAM_PTR de_param; + + switch ( vfs_id ) + { + case VFS_IPC_MOUNT: + assert( message_type== MESSAGE_TYPE_REFERENCE ); + assert( IPR_ARGUMENT_ADDRESS != NULL ); + /*devfs supports mounting only one device*/ + if ( strcmp(IPR_ARGUMENT_ADDRESS, DEV_FS_MOUNT_DEVICE) == 0 ) + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, NULL, NULL, NULL, NULL, NULL ); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_INVALID_PARAMETER, NULL, NULL, NULL, NULL, NULL ); + break; + case VFS_IPC_UNMOUNT: + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_OPERATION_NOT_SUPPORTED, NULL, NULL, NULL, NULL, NULL ); + break; + case VFS_IPC_GET_DIR_ENTRIES: + assert( message_type == MESSAGE_TYPE_REFERENCE ); + de_param = (DIRECTORY_ENTRY_PARAM_PTR )IPR_ARGUMENT_ADDRESS; + de = GetDirectoryEntries( arg2, -1, NULL, de_param->max_entries, &total_entries); + if( total_entries > 0 ) + ReplyToLastMessage( MESSAGE_TYPE_REFERENCE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, (IPC_ARG_TYPE)total_entries, NULL, NULL, de, (IPC_ARG_TYPE) (sizeof(FILE_STAT_PARAM)*total_entries)); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_NOT_FOUND, NULL, NULL, NULL, NULL, NULL ); + break; + case VFS_IPC_GET_FILE_STAT_PATH: + assert( message_type == MESSAGE_TYPE_REFERENCE ); + de = GetDirectoryEntries( arg2, -1, IPR_ARGUMENT_ADDRESS, 1, NULL ); + if( de ) + ReplyToLastMessage( MESSAGE_TYPE_REFERENCE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, (IPC_ARG_TYPE)1, NULL, NULL, de, (IPC_ARG_TYPE) sizeof(FILE_STAT_PARAM)); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_NOT_FOUND, NULL, NULL, NULL, NULL, NULL ); + break; + + case VFS_IPC_GET_FILE_STAT_INODE: + case VFS_IPC_READ_FILE: + case VFS_IPC_WRITE_FILE: + case VFS_IPC_MAP_FILE_PAGE: + case VFS_IPC_DELETE_FILE: + case VFS_IPC_MOVE: + case VFS_IPC_CREATE_SOFT_LINK: + case VFS_IPC_CREATE_HARD_LINK: + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_INVALID_PARAMETER, NULL, NULL, NULL, NULL, NULL ); + break; + } +} + +/*! Creates a special device file under /device + * \param filename - file name to create under /device folder + * \param device - device object associated + * */ +ERROR_CODE CreateDeviceNode(const char * filename, DEVICE_OBJECT_PTR device) +{ + DEVFS_METADATA_PTR dp=NULL; + + assert(device != NULL); + + if( filename == NULL || strlen(filename) > DEVFS_FILE_NAME_MAX-1 ) + return ERROR_INVALID_PARAMETER; + + dp = AllocateBuffer(&devfs_cache, 0); + if ( dp == NULL ) + return ERROR_NOT_ENOUGH_MEMORY; + + strcpy( dp->name, filename ); + if ( InsertNodeIntoAvlTree(&devfs_root, &dp->tree, 0, compare_dev_node_name ) != 0 ) + return ERROR_INVALID_PARAMETER; + + dp->device = device; + + devfs_total_directory_entries++; + + return ERROR_SUCCESS; +} + +/*! Returns the directory entries for a given directory + \param fs_data - fs provided data for the directory during open file if any + \param inode - inode of the file else -1 + \param file_name - name of the file else NULL + \param max_entries - maximum entries required + \param total_entries - output - total entries in the array + \return Array of directory entries +*/ +static FILE_STAT_PARAM_PTR GetDirectoryEntries(void * fs_data, int inode, char * file_name, int max_entries, int * total_entries) +{ + int total_directory_entries = devfs_total_directory_entries; + FILE_STAT_PARAM_PTR result=NULL; + DEVFS_DIRENTRY_PARAM param={0}; + + if ( total_entries ) + * total_entries = 0; + if ( max_entries < total_directory_entries) + total_directory_entries = max_entries; + result = kmalloc( sizeof(FILE_STAT_PARAM)*total_directory_entries, 0 ); + if ( result == NULL ) + return NULL; + + param.file_stat = result; + param.max_entries = max_entries; + EnumerateAvlTree(devfs_root, enumerate_devfs_tree_callback, ¶m); + + /*if no entry is reterived free the memory and return null*/ + if( param.current_index == 0 ) + { + kfree( result ); + return NULL; + } + + if ( total_entries ) + * total_entries = param.current_index; + + return result; +} + +/*! Searches the vm descriptor AVL tree for a particular VA range*/ +static COMPARISION_RESULT compare_dev_node_name(struct binary_tree * node1, struct binary_tree * node2) +{ + DEVFS_METADATA_PTR d1, d2; + int result; + assert( node1 != NULL ); + assert( node2 != NULL ); + + d1 = STRUCT_ADDRESS_FROM_MEMBER(node1, DEVFS_METADATA, tree.bintree); + d2 = STRUCT_ADDRESS_FROM_MEMBER(node2, DEVFS_METADATA, tree.bintree); + + result = strcmp( d1->name, d2->name ); + if( result == 0 ) + return EQUAL; + else if ( result > 0 ) + return GREATER_THAN; + else + return LESS_THAN; +} + +/*! Enumerates devfs tree and fills the FILE_STAT_PARAM for each node*/ +int enumerate_devfs_tree_callback(AVL_TREE_PTR node, void * arg) +{ + DEVFS_METADATA_PTR dm; + DEVFS_DIRENTRY_PARAM_PTR param; + FILE_STAT_PARAM_PTR fstat_param; + + dm = STRUCT_ADDRESS_FROM_MEMBER(node, DEVFS_METADATA, tree); + param = (DEVFS_DIRENTRY_PARAM_PTR)arg; + + assert( param->current_index < param->max_entries ); + + fstat_param = ¶m->file_stat[ param->current_index ]; + param->current_index++; + + /*fill the entry*/ + strcpy( fstat_param->name, dm->name ); + fstat_param->inode = 0; + fstat_param->file_size = 0; + fstat_param->mode = 0; + fstat_param->fs_data = dm->device; + + /*if no more free slot available break enumeration*/ + if ( param->current_index == param->max_entries ) + return 1; + + /*continue enumeration*/ + return 0; +} + + +/*! Internal function used to initialize the devfs metadata structure*/ +int DevFsCacheConstructor( void *buffer) +{ + DEVFS_METADATA_PTR dp = (DEVFS_METADATA_PTR) buffer; + + dp->name[0]=0; + InitAvlTreeNode( &dp->tree, 0 ); + + return 0; +} + +/*! Internal function used to clear the devfs metadata structure*/ +int DevFsCacheDestructor( void *buffer) +{ + DevFsCacheConstructor( buffer ); + return 0; +} + Added: src/kernel/iom/driver.c =================================================================== --- src/kernel/iom/driver.c (rev 0) +++ src/kernel/iom/driver.c 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,168 @@ +/*! + \file kernel/iom/driver.c + \brief driver loand and unloading routines. +*/ +#include <ace.h> +#include <string.h> +#include <ctype.h> +#include <kernel/debug.h> +#include <kernel/mm/kmem.h> +#include <kernel/pm/elf.h> +#include <kernel/iom/iom.h> +#include <kernel/vfs/vfs.h> + +extern LIST_PTR driver_list_head; + +ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length); + +/*! Loads a driver*/ +DRIVER_OBJECT_PTR LoadDriver(char * device_id) +{ + char driver_file_name[MAX_FILE_NAME], driver_file_path[MAX_FILE_PATH]="/boot/drivers/"; + VADDR driver_start_address; + int file_id; + long file_size; + DRIVER_OBJECT_PTR driver_object; + ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); + ERROR_CODE err; + LIST_PTR node; + + err = FindDriverFile(device_id, driver_file_name, sizeof(driver_file_name)); + ktrace("Driver for id %s : ", device_id); + if ( err == ERROR_SUCCESS ) + ktrace("%s\n", driver_file_name); + else + { + ktrace("%s\n", ERROR_CODE_AS_STRING(err) ); + return NULL; + } + + /*check whether the driver is already loaded*/ + LIST_FOR_EACH(node, driver_list_head) + { + driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); + if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) + { + ktrace("Driver already loaded %s\n", driver_object->driver_file_name); + return driver_object; + } + + } + strcat( driver_file_path, driver_file_name ); + kprintf("Loading %s: ", driver_file_path); + + err = OpenFile(driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + if ( err != ERROR_SUCCESS ) + goto error; + err = GetFileSize(file_id, &file_size); + if ( err != ERROR_SUCCESS ) + goto error; + file_size = PAGE_ALIGN_UP(file_size); + err = MapViewOfFile(file_id, &driver_start_address, PROT_READ, 0, file_size, 0, 0); + if ( err != ERROR_SUCCESS ) + goto error; + err = LoadElfImage( (void *) driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); + if ( err != ERROR_SUCCESS || DriverEntry == NULL ) + goto error; + driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); + if ( driver_object == NULL ) + { + err = ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + + strcpy( driver_object->driver_file_name, driver_file_name); + err = DriverEntry( driver_object ); + if ( err != ERROR_SUCCESS ) + goto error; + + /*add the driver to the driver list*/ + AddToList( driver_list_head, &driver_object->driver_list ); + kprintf("success\n"); + return driver_object; + +error: + kprintf("%s\n", ERROR_CODE_AS_STRING(err) ); + return NULL; + +} + +#define SKIP_WHITE_SPACES while( i<file_size && isspace(va[i]) ) i++; + + +/*! Finds suitable driver for the given id and returns its full path in the given buffer + \param device_id - device identification string + \param buffer - buffer to place the driver path + \param buf_length - buffer size +*/ +ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length) +{ + ERROR_CODE err; + int file_id,i=0; + long file_size; + char driver_id_database[] = "/boot/driver_id.txt"; + char * va; + + assert(device_id != NULL ); + assert(buffer != NULL ); + assert(buf_length > 0); + + buffer[0]=0; + + err = OpenFile(driver_id_database, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + if ( err != ERROR_SUCCESS ) + goto done; + + err = GetFileSize(file_id, &file_size); + if ( err != ERROR_SUCCESS ) + goto done; + + err = MapViewOfFile(file_id, (VADDR *) &va, PROT_READ, 0, file_size, 0, 0); + if ( err != ERROR_SUCCESS ) + goto done; + + err=ERROR_NOT_FOUND; + /*read the file and try to find the driver file name*/ + while(i<file_size) + { + char driver_device_id[100]; + SKIP_WHITE_SPACES; + + /*if the line not starting with comment character process it*/ + if( va[i]!='#' ) + { + int j=0; + + /*copy the driver id*/ + while( i<file_size && j<sizeof(driver_device_id)-1 && !isspace(va[i]) ) + driver_device_id[j++] = va[i++]; + driver_device_id[j]=0; + + /*if user didnt provide driver file name break*/ + if ( va[i] != ' ' && va[i] != '\t' ) + break; + + SKIP_WHITE_SPACES; + + if( strcmp(driver_device_id, device_id) == 0 ) + { + /*copy driver file name*/ + j=0; + while( i<file_size && j<buf_length-1 && !isspace(va[i]) ) + buffer[j++] = va[i++]; + + buffer[j]=0; + err = ERROR_SUCCESS; + break; + } + } + /*skip till end of line*/ + while( i<file_size && va[i]!='\n') i++; + } + +done: + /* \todo - release the mapping */ + + CloseFile(file_id); + return err; +} Modified: src/kernel/iom/iom.c =================================================================== --- src/kernel/iom/iom.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/kernel/iom/iom.c 2009-06-09 17:03:41 UTC (rev 366) @@ -10,6 +10,7 @@ #include <kernel/pm/elf.h> #include <kernel/iom/iom.h> #include <kernel/vfs/vfs.h> +#include <kernel/iom/devfs.h> #define DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD 10 #define DEVICE_OBJECT_CACHE_MIN_BUFFERS 10 @@ -23,8 +24,6 @@ #define IRP_CACHE_MIN_BUFFERS 50 #define IRP_CACHE_MAX_SLABS 50 -static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); - /*! List of drivers loaded into the kernel address space */ LIST_PTR driver_list_head = NULL; @@ -34,74 +33,25 @@ /*! cache for irps*/ CACHE irp_cache; -static DRIVER_OBJECT_PTR LoadDriver(char * device_id); -static ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length); +extern DRIVER_OBJECT_PTR LoadDriver(char * device_id); +extern ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length); +static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); +int DriverObjectCacheConstructor( void * buffer); +int DriverObjectCacheDestructor( void *buffer); +int DeviceObjectCacheConstructor( void *buffer); +int DeviceObjectCacheDestructor( void *buffer); +int IrpCacheConstructor( void * buffer); +int IrpCacheDestructor( void * buffer); -/*! Internal function used to initialize the driver object structure*/ -int DriverObjectCacheConstructor( void * buffer) -{ - int i; - DRIVER_OBJECT_PTR dop = (DRIVER_OBJECT_PTR) buffer; - - memset(dop, 0, sizeof(DRIVER_OBJECT) ); +extern void InitDevFs(); - InitList( &dop->driver_list ); - InitSpinLock( &dop->lock ); - for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) - dop->fn.MajorFunctions[i] = DummyMajorFunction; - - return 0; -} -/*! Internal function used to clear the driver object structure*/ -int DriverObjectCacheDestructor( void *buffer) -{ - DriverObjectCacheConstructor( buffer ); - return 0; -} -/*! Internal function used to initialize the device object structure*/ -int DeviceObjectCacheConstructor( void *buffer) -{ - DEVICE_OBJECT_PTR dop = (DEVICE_OBJECT_PTR) buffer; - - memset(buffer, 0, sizeof(DEVICE_OBJECT) ); - - InitSpinLock( &dop->lock ); - InitList( &dop->sibilings_list ); - InitList( &dop->device_object_list ); - - dop->stack_count = 1; - - return 0; -} -/*! Internal function used to clear the device object structure*/ -int DeviceObjectCacheDestructor( void *buffer) -{ - DeviceObjectCacheConstructor( buffer ); - return 0; -} - -/*! Internal function used to initialize the IRP structure*/ -int IrpCacheConstructor( void * buffer) -{ - memset(buffer, 0, sizeof(IRP) ); - - return 0; -} - -/*! Internal function used to initialize the IRP structure*/ -int IrpCacheDestructor( void * buffer) -{ - IrpCacheConstructor(buffer); - - return 0; -} - /*! Initialize IO manager and start required boot drivers*/ void InitIoManager() { DRIVER_OBJECT_PTR root_bus; + /*initialize cache objects for io manager*/ if( InitCache(&driver_object_cache, sizeof(DRIVER_OBJECT), DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DRIVER_OBJECT_CACHE_MIN_BUFFERS, DRIVER_OBJECT_CACHE_MAX_SLABS, DriverObjectCacheConstructor, DriverObjectCacheDestructor) ) panic("InitIoManager - Driver object cache init failed"); @@ -110,6 +60,9 @@ if( InitCache(&irp_cache, sizeof(IRP), IRP_CACHE_FREE_SLABS_THRESHOLD, IRP_CACHE_MIN_BUFFERS, IRP_CACHE_MAX_SLABS, IrpCacheConstructor, IrpCacheDestructor) ) panic("InitIoManager - IRP cache init failed"); + + /*initialize dev fs*/ + InitDevFs(); /*load root bus driver and call the DriverEntry*/ root_bus = LoadRootBusDriver() ; @@ -120,7 +73,7 @@ RootBusDriverEntry( root_bus ); /*create device object for root bus*/ - CreateDevice(root_bus_driver_object, 0, &root_bus_device_object); + CreateDevice(root_bus_driver_object, 0, &root_bus_device_object, NULL); /*force the io manager to enumerate the buses on root bus*/ InvalidateDeviceRelations(root_bus_device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -139,30 +92,13 @@ return ERROR_NOT_SUPPORTED; } -/*! Returns the current IO Stack location associated with the given IRP - \param irp - interrupt request packet - \return Current IO stack location on the given irp -*/ -IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp) -{ - return Irp->current_stack_location; -} - -/*! Returns the next lower level IO Stack location associated with the given IRP - \param irp - interrupt request packet - \return Next IO stack loation on the given irp. -*/ -IO_STACK_LOCATION_PTR GetNextIrpStackLocation(IRP_PTR Irp) -{ - assert( Irp->current_stack >0 && Irp->current_stack < Irp->stack_count ); - return Irp->current_stack_location-1; -} /*! Creates a device object for use by the driver \param driver_object - caller's driver object - this is used by io manager to link the created device with the driver \param device_extension_size - size of the device_externsion - io manager allocates this much byte in the device_object \param device_object - pointer to device object - io manager updates this pointer with the newly created device object + \param device_name - optional - device file name - it will be placed under /device/xxxx - applications use this file to communicate with the driver */ -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object) +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name) { DEVICE_OBJECT_PTR dob; assert( device_object != NULL ); @@ -179,6 +115,14 @@ driver_object->device_object_head = dob; else AddToListTail( &driver_object->device_object_head->device_object_list, &dob->device_object_list ); + + /*create a device file if name is provided*/ + if ( device_name ) + { + ERROR_CODE ret; + ret = CreateDeviceNode(device_name, dob); + /*\todo - do we need to care about CreateDeviceNode return status?*/ + } *device_object = dob; return ERROR_SUCCESS; @@ -264,59 +208,6 @@ FreeIrp(irp); } -/*! Allocates a Irp for the use of driver - \param stack_size - number of stacks assoicated with this irp - \return irp -*/ -IRP_PTR AllocateIrp(BYTE stack_size) -{ - IRP_PTR irp; - - assert( stack_size>0 ); - /*! allocate irp and io stack*/ - irp = AllocateBuffer( &irp_cache, CACHE_ALLOC_SLEEP ); - if ( irp == NULL ) - return NULL; - irp->current_stack_location = kmalloc( sizeof(IO_STACK_LOCATION)*stack_size, KMEM_NO_FAIL ); - - irp->stack_count = stack_size; - irp->io_status.status = ERROR_NOT_SUPPORTED; - - return irp; -} - -/*! Frees a irp - \param irp - pointer to irp to be freed -*/ -void FreeIrp(IRP_PTR irp) -{ - assert( irp != NULL ); - - kfree( irp->current_stack_location ); - FreeBuffer( irp, &irp_cache ); -} - -/*! Reuses a already allocated Irp - \param irp - pointer to irp - \param error_code - Io status will be set with this error code -*/ -void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code) -{ - BYTE stack_size; - IO_STACK_LOCATION_PTR io_stack; - - assert( irp != NULL ); - - stack_size = irp->stack_count; - io_stack = irp->current_stack_location; - - IrpCacheConstructor( irp ); - - irp->current_stack_location = io_stack; - irp->stack_count = stack_size; - irp->io_status.status = error_code; -} - /*! Dispatches a call to driver based on the given Irp \param device_object - device object \param irp - irp @@ -330,165 +221,63 @@ return ERROR_SUCCESS; } -/*Helper routine to fill a Io Stack with given information*/ -inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context) -{ - assert( io_stack ); - io_stack->major_function = major_function; - io_stack->minor_function = minor_function; - io_stack->device_object = device_object; - io_stack->completion_routine = completion_routine; - io_stack->context = context; -} -/*! Loads a driver*/ -static DRIVER_OBJECT_PTR LoadDriver(char * device_id) +/*! Internal function used to initialize the driver object structure*/ +int DriverObjectCacheConstructor( void * buffer) { - char driver_file_name[MAX_FILE_NAME], driver_file_path[MAX_FILE_PATH]="/boot/drivers/"; - VADDR driver_start_address; - int file_id; - long file_size; - DRIVER_OBJECT_PTR driver_object; - ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); - ERROR_CODE err; - LIST_PTR node; + int i; + DRIVER_OBJECT_PTR dop = (DRIVER_OBJECT_PTR) buffer; - err = FindDriverFile(device_id, driver_file_name, sizeof(driver_file_name)); - ktrace("Driver for id %s : ", device_id); - if ( err == ERROR_SUCCESS ) - ktrace("%s\n", driver_file_name); - else - { - ktrace("%s\n", ERROR_CODE_AS_STRING(err) ); - return NULL; - } + memset(dop, 0, sizeof(DRIVER_OBJECT) ); - /*check whether the driver is already loaded*/ - LIST_FOR_EACH(node, driver_list_head) - { - driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); - if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) - { - ktrace("Driver already loaded %s\n", driver_object->driver_file_name); - return driver_object; - } - - } - strcat( driver_file_path, driver_file_name ); - kprintf("Loading %s: ", driver_file_path); + InitList( &dop->driver_list ); + InitSpinLock( &dop->lock ); + for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) + dop->fn.MajorFunctions[i] = DummyMajorFunction; - err = OpenFile(driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); - if ( err != ERROR_SUCCESS ) - goto error; - err = GetFileSize(file_id, &file_size); - if ( err != ERROR_SUCCESS ) - goto error; - file_size = PAGE_ALIGN_UP(file_size); - err = MapViewOfFile(file_id, &driver_start_address, PROT_READ, 0, file_size, 0, 0); - if ( err != ERROR_SUCCESS ) - goto error; - err = LoadElfImage( (void *) driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); - if ( err != ERROR_SUCCESS || DriverEntry == NULL ) - goto error; - driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); - if ( driver_object == NULL ) - { - err = ERROR_NOT_ENOUGH_MEMORY; - goto error; - } + return 0; +} +/*! Internal function used to clear the driver object structure*/ +int DriverObjectCacheDestructor( void *buffer) +{ + DriverObjectCacheConstructor( buffer ); + return 0; +} +/*! Internal function used to initialize the device object structure*/ +int DeviceObjectCacheConstructor( void *buffer) +{ + DEVICE_OBJECT_PTR dop = (DEVICE_OBJECT_PTR) buffer; - strcpy( driver_object->driver_file_name, driver_... [truncated message content] |