#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