#ifndef __OS_H #define __OS_H #ifdef __cplusplus extern "C" { #endif #include <sys/types.h> /*! * \ingroup kernelu * @{ */ typedef struct module_info_t module_info_t; //! Specifies user-mode information on a specific module. /*! * This structure is part of the module itself (it has its own section -- * .info). The crt0 code (crt0.c) is responsible for declaring this * variable. When the module loader loads a section with the name ".info" * it assumes that it comprises a structure of this format, and fills it * in accordingly. * * This structure is available through the _info variable in each module. */ struct module_info_t { //! Specifies the version number of the module loader that loaded this //! module. dword loader_version; //! Points to the module loaded immediately after this one, or NULL if this //! was the last module to be loaded. module_info_t* next; //! Specifies the base address of the module. /*! * The base address is the address where the module's headers start. */ dword base, //! Specifies the overall length of the module, in bytes. /*! * Includes headers, all sections and alignment padding. */ length; //! Specifies the name of the module. wchar_t name[40]; }; extern module_info_t _info; #include <kernel/i386.h> #pragma pack(push,1) //! The layout of the stack frame generated by the assembly-language interrupt //! handler. /*! * The isr_and_switch routine (in start.asm), along with the individual * interrupt handlers and the processor, build this structure on the stack * before isr() is called. */ struct context_t { /* //! The user-mode registers pushed by pusha. pusha_t regs; //! The user-mode selectors pushed by isr_and_switch. dword ds, es, fs, gs; //! The interrupt or IRQ number pushed by the interrupt handler. dword intr, //! The error code pushed by the processor. error; //! The current context pushed by the processor. dword eip, cs, eflags, esp, ss; */ dword kernel_esp; pusha_t regs; dword gs, fs, es, ds; dword intr, error; dword eip, cs, eflags, esp, ss; }; typedef struct context_t context_t; #pragma pack(pop) typedef enum _ExceptionDisposition { ExceptionContinueExecution, ExceptionContinueSearch, ExceptionNestedException, ExceptionCollidedUnwind } ExceptionDisposition; typedef struct exception_info_t exception_info_t; struct exception_info_t { dword code; addr_t address; addr_t eip; }; typedef ExceptionDisposition (*except_handler)( exception_info_t *ExceptionRecord, void * EstablisherFrame, context_t *ContextRecord, void * DispatcherContext); typedef struct exception_registration_t exception_registration_t; struct exception_registration_t { exception_registration_t* prev; except_handler handler; }; typedef struct process_info_t process_info_t; typedef struct thread_info_t thread_info_t; //! Specifies user-mode thread information. /*! * When a thread is created, the kernel allocates space in the process's * address space for a thread_info_t structure. This structure is freely * readable by the process itself and includes important information about * the thread's environment. The use of a structure like this, in user- * accessible memory, is more efficient than a series of syscalls to query * the relevant information. * * The thread_info_t structure forms each thread's FS segment. A pointer to * the thread_info_t structure, in DS-addressable form, is provided, to * make the structure more easily accessible from high-level languages. */ struct thread_info_t { //! Points to a structure specifying the exception handler for the current //! block of code. exception_registration_t* except; //! Points to the thread_info_t structure itself, allowing the structure to //! be accessed without referring to the FS selector. thread_info_t* info; //! Specifies the thread's ID dword tid; //! Specifies the ID of the thread's parent process dword pid; //! Describes the error condition which caused the last operating system //! call to fail, if any. Analogous to the C run-time errno variable. dword last_error; //! Points to the thread's parent process's information structure. process_info_t* process; dword queue; }; #define EXCEPTION_DEBUG 1 #define EXCEPTION_GPF 13 #define EXCEPTION_PAGE_FAULT 14 #define EXCEPTION_MISSING_DLL 0x80000000 #define EXCEPTION_MISSING_IMPORT 0x80000001 #define EXCEPTION_DLLMAIN_FAILED 0x80000002 #define EXCEPTION_ASSERT_FAILED 0x80000003 //! Specifies user-mode process information. /*! * When a process is created, the kernel allocates space in its address space * for a process_info_t structure. This structure is freely readable by * the process itself and includes important information about its * environment. The use of a structure like this, in user-accessible * memory, is more efficient than a series of syscalls to query the * relevant information. * * The process_info_t structure is accessible through the process member of * each thread's thread_info_t structure, which forms each thread's FS * segment. */ struct process_info_t { //! The ID of the process; unique within the system dword id; //! A pointer to the process's root IFolder object void* root; //! Points to a buffer containing the process's initial command line wchar_t* cmdline; //! Points to the the module_info_t structure relating to the first module //! loaded. Subsequent module_info_t's form a linked list through each //! module's next member. module_info_t* module_first; //! Contains the process's current working directory, as a fully-qualified path wchar_t cwd[256]; wchar_t *environment; addr_t base; addr_t input, output; }; #ifdef _MSC_VER #pragma warning(disable:4035) __inline thread_info_t* thrGetInfo() { __asm mov eax, fs:[4] } #pragma warning(default:4035) #else //! Retrieves a pointer to the current thread's thread_info_t structure. static inline thread_info_t* thrGetInfo() { thread_info_t* ret; asm("mov %%fs:(4), %0" : "=r" (ret)); return ret; } #endif #ifndef callconv_defined #ifdef _MSC_VER #define STDCALL __stdcall #define CDECL __cdecl #else #define STDCALL __attribute__((stdcall)) #define CDECL __attribute__((cdecl)) #endif #define callconv_defined #endif #ifndef KERNEL /*! * \ingroup kernelu * \defgroup proc Processes * @{ */ dword procLoad(const wchar_t* filespec, const wchar_t* cmdline, unsigned priority, addr_t input, addr_t output); void procExit(); dword procCurrentId(); wchar_t* procCmdLine(); wchar_t* procCwd(); addr_t procBase(); //@} /*! * \ingroup kernelu * \defgroup sys General System * @{ */ addr_t sysOpen(const wchar_t* filespec); dword sysInvoke(void* obj, dword method, ...); void sysSetErrno(int errno); int sysErrno(); dword sysUpTime(); bool sysGetErrorText(status_t stat, wchar_t* text, size_t max); //@} /*! * \ingroup kernelu * \defgroup thr Threads * @{ */ #define THREAD_PRIORITY_NORMAL 16 void thrSetTls(dword value); dword thrGetTls(); void thrCall(void* addr, void* params, size_t sizeof_params); void thrSleep(dword ms); unsigned thrWaitHandle(addr_t* hnd, unsigned num_handles, bool wait_all); thread_info_t* thrGetInfo(); dword thrGetId(); addr_t thrCreate(void* entry_point, dword param, unsigned priority); void thrExit(int code); //@} typedef struct { dword unused; } *marshal_t; marshal_t objMarshal(void* ptr); void* objUnmarshal(marshal_t mshl); void objNotifyDelete(marshal_t mshl); /*! * \ingroup kernelu * \defgroup vmm Virtual Memory Manager * @{ */ void* vmmAlloc(size_t pages, addr_t start, dword flags); //@} //! Defines the entry point to a dynamic link library (DLL). /*! * Every DLL is notified of certain events relevant to its execution, such * as being loaded into and unloaded from a process's address space, * and the creation and deletion of a process's threads. The DllMain() * function provides a way of the kernel notifying the library of such * events. * \param reserved1 Reserved on The Möbius; corresponds to the HINSTANCE * parameter on Win32. * \param reason Specifies the reason for calling DllMain * \param reserved2 Reserved on The Möbius * \return true if successful (e.g. if the DLL is to be allowed to load); * false otherwise. */ bool STDCALL DllMain(dword reserved1, dword reason, void* reserved2); #endif /* * All the following functions are implemented both in the kernel and in * kernelu.dll. They may be called from either kernel or user mode. */ /*! * \defgroup res Resources * \ingroup kernelu * * Because it uses the Portable Executable format, The Möbius is able to embed * resources into executables. These can be accessed easily from user * mode, since they are stored in their own section in the module, and are * organised in a tree structure, by type/ID/language. * * The resXXX() functions will load the different resource types; resFind() * can be used to load all resources, including ones with user-defined * types. * * @{ */ const void* resFind(dword base, word type, word id, word language); bool resLoadString(dword base, word id, wchar_t* str, size_t str_max); /*! * \defgroup RT Resource Type Identifiers * * These are the same as the standard Windows numerical resource IDs. They * identify module resource types and can be used with the resFind() * function. * * It is also possible to define new resource types. * \note The Möbius does not currently support string resource or type IDs. * @{ */ //! Cursor #define RT_CURSOR 1 //! Bitmap #define RT_BITMAP 2 //! Icon #define RT_ICON 3 //! Menu #define RT_MENU 4 //! Dialog box #define RT_DIALOG 5 //! Block of 16 strings #define RT_STRING 6 //! Font list #define RT_FONTDIR 7 //! Font #define RT_FONT 8 //! Acclerator table #define RT_ACCEL 9 //! Arbitrary binary data #define RT_RCDATA 10 //! Table of error messages #define RT_MSGTABLE 11 //! Group of cursors describing the same image at different resolutions and //! colour depths #define RT_GROUP_CURSOR 12 //! Group of icons describing the same image at different resolutions and //! colour depths #define RT_GROUP_ICON 13 //! Module version information block #define RT_VERSION 16 /*! @} @} */ /*! * \ingroup vmm * @{ */ //! Specifies that the area can only be accessed by the kernel #define MEM_KERNEL 0 //! Specifies that the area can be accessed in user mode #define MEM_USER 3 //! Causes the area to be committed when it is allocated #define MEM_COMMIT 0x4 //! Allows the area to be read from #define MEM_READ 0x8 //! Allows the area to be written to #define MEM_WRITE 0x10 //! Causes the area to be zeroed when it is committed #define MEM_ZERO 0x20 //! Specifies that the start parameter to vmmAlloc() refers to a physical //! address which has already been allocated in the process's address space. #define MEM_LITERAL 0x40 //! For memory-mapped files, specifies that the file is an executable image //! and that the memory alignment is independent of the file alignment #define MEM_FILE_IMAGE 0x80 //@} //@} addr_t hndGetOwner(addr_t handle); #ifndef KERNEL typedef struct semaphore_t semaphore_t; struct semaphore_t { addr_t owner; int locks; }; void semInit(semaphore_t* sem); void semAcquire(semaphore_t* sem); void semRelease(semaphore_t* sem); #endif #ifdef __cplusplus } #endif #endif