KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o\r
KERNEL_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o vfs/select.o\r
KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o\r
-KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o\r
+KERNEL_OBJ += drv/fifo.o drv/proc.o\r
+KERNEL_OBJ += drv/vterm.o drv/vterm_font.o drv/vterm_vt100.o drv/vterm_output.o drv/vterm_input.o drv/vterm_termbuf.o\r
\r
N_OBJ := main.o\r
\r
// === GLOBALS ===
MODULE_DEFINE(0, 0x0100, NativeKeyboard, NativeKeyboard_Install, NULL, NULL);
+tVFS_NodeType gKB_NodeType = {
+ .IOCtl = NativeKeyboard_IOCtl
+};
tDevFS_Driver gKB_DevInfo = {
NULL, "NativeKeyboard",
- {
- .NumACLs = 0,
- .Size = 0,
- .IOCtl = NativeKeyboard_IOCtl
- }
+ { .Type = &gKB_NodeType }
};
// === CODE ===
Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
\r
// === GLOBALS ===\r
+tVFS_NodeType gNativeFS_FileNodeType = {\r
+ .Read = NativeFS_Read\r
+};\r
+tVFS_NodeType gNativeFS_DirNodeType = {\r
+ .FindDir = NativeFS_FindDir,\r
+ .ReadDir = NativeFS_ReadDir,\r
+};\r
tVFS_Driver gNativeFS_Driver = {\r
"nativefs", 0,\r
NativeFS_Mount, NativeFS_Unmount,\r
ret->ImplInt = strlen(ret->Data);\r
ret->ImplPtr = info;\r
ret->Inode = (Uint64)dp;\r
- \r
- ret->FindDir = NativeFS_FindDir;\r
- ret->ReadDir = NativeFS_ReadDir;\r
+\r
+ ret->Type = &gNativeFS_DirNodeType; \r
\r
return ret;\r
}\r
{\r
LOG("Directory");\r
baseRet.Inode = (Uint64) opendir(path);\r
- baseRet.FindDir = NativeFS_FindDir;\r
- baseRet.ReadDir = NativeFS_ReadDir;\r
+ baseRet.Type = &gNativeFS_DirNodeType;\r
baseRet.Flags |= VFS_FFLAG_DIRECTORY;\r
baseRet.Size = -1;\r
}\r
{\r
LOG("File");\r
baseRet.Inode = (Uint64) fopen(path, "r+");\r
- baseRet.Read = NativeFS_Read;\r
+ baseRet.Type = &gNativeFS_FileNodeType;\r
\r
fseek( (FILE*)(tVAddr)baseRet.Inode, 0, SEEK_END );\r
baseRet.Size = ftell( (FILE*)(tVAddr)baseRet.Inode );\r
typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
// === MACROS ===
+#define SYSCALL6(_name, _fmtstr, _t0, _t1, _t2, _t3, _t4, _t5, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
+ _t0 a0;_t1 a1;_t2 a2;_t3 a3;_t4 a4;_t5 a5;\
+ if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ a0 = *(_t0*)Args;Args+=sizeof(_t0);\
+ a1 = *(_t1*)Args;Args+=sizeof(_t1);\
+ a2 = *(_t2*)Args;Args+=sizeof(_t2);\
+ a3 = *(_t3*)Args;Args+=sizeof(_t3);\
+ a4 = *(_t4*)Args;Args+=sizeof(_t4);\
+ a5 = *(_t5*)Args;Args+=sizeof(_t5);\
+ LOG("SYSCALL5 '%s' %p %p %p %p %p %p", Fmt, (intptr_t)a0,(intptr_t)a1,(intptr_t)a2,(intptr_t)a3,(intptr_t)a4,(intptr_t)a5);\
+ _call\
+}
#define SYSCALL5(_name, _fmtstr, _t0, _t1, _t2, _t3, _t4, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
_t0 a0;_t1 a1;_t2 a2;_t3 a3;_t4 a4;\
if(strcmp(Fmt,_fmtstr)!=0)return 0;\
return -1;
return VFS_ReadDir(a0, a1);
);
-SYSCALL5(Syscall_select, "idddd", int, fd_set *, fd_set *, fd_set *, time_t *,
- return VFS_Select(a0, a1, a2, a3, a4, 0);
+SYSCALL6(Syscall_select, "iddddi", int, fd_set *, fd_set *, fd_set *, time_t *, unsigned int,
+ return VFS_Select(a0, a1, a2, a3, a4, a5, 0);
);
SYSCALL3(Syscall_OpenChild, "isi", int, const char *, int,
return VFS_OpenChild(a0, a1, a2|VFS_OPENFLAG_USER);
*Errno = -EINVAL; // TODO: Better message
return -1;
}
- return Threads_SetUID(Errno, a0);
+ return Threads_SetUID(a0);
);
SYSCALL1(Syscall_SetGID, "i", int,
if(Sizes[0] < sizeof(int)) {
*Errno = -EINVAL; // TODO: Better message
return -1;
}
- return Threads_SetGID(Errno, a0);
+ return Threads_SetGID(a0);
);
SYSCALL1(Syscall_Fork, "d", int *,
} tState;
#endif
+typedef struct sProcess
+{
+ int nThreads;
+ int NativePID;
+ char *CWD;
+ char *Chroot;
+ int MaxFD;
+} tProcess;
+
typedef struct sThread
{
struct sThread *GlobalNext;
int State; // 0: Dead, 1: Active, 2: Paused, 3: Asleep
int ExitStatus;
- #if 0
- tState CurState;
- #endif
+ int _errno;
// Threads waiting for this thread to exit.
// Quit logic:
struct sThread *WaitingThreads;
struct sThread *WaitingThreadsEnd;
- // Config?
- Uint Config[NUM_CFG_ENTRIES];
+ tProcess *Process;
+
} tThread;
// === PROTOTYPES ===
int Threads_Wake(tThread *Thread);
// === GLOBALS ===
+tProcess gProcessZero = {
+ .NativePID = 0,
+ .CWD = "/",
+ .Chroot = "/",
+ .MaxFD = 100
+};
tThread gThreadZero = {
.State=1,
- .ThreadName="ThreadZero"
+ .ThreadName="ThreadZero",
+ .Process = &gProcessZero
};
tThread *gpThreads = &gThreadZero;
__thread tThread *gpCurrentThread = &gThreadZero;
int giThreads_NextThreadID = 1;
// === CODE ===
+tThread *Proc_GetCurThread(void)
+{
+ return gpCurrentThread;
+}
+
void Threads_Dump(void)
{
tThread *thread;
return 0;
}
-Uint *Threads_GetCfgPtr(int Index)
-{
-// Log_Debug("Threads", "Index=%i, gpCurrentThread=%p",
-// Index, gpCurrentThread);
- if( Index < 0 || Index >= NUM_CFG_ENTRIES )
- return NULL;
- if( !gpCurrentThread )
- return NULL;
- return &gpCurrentThread->Config[Index];
-}
+int *Threads_GetErrno(void) { return &gpCurrentThread->_errno; }
+char **Threads_GetCWD(void) { return &gpCurrentThread->Process->CWD; }
+char **Threads_GetChroot(void) { return &gpCurrentThread->Process->Chroot; }
+int *Threads_GetMaxFD(void) { return &gpCurrentThread->Process->MaxFD; };
int Threads_WaitTID(int TID, int *Status)
{
return AmmountToAdd;
}
-#if 0
-void Threads_Sleep()
-{
- gpCurrentThread->State = 3;
- if( setjmp(&gpCurrentThread->CurState) == 0 ) {
- // Return to user wait
- // Hmm... maybe I should have a "kernel" thread for every "user" thread
- }
- else {
- // Just woken up, return
- return ;
- }
-}
-
-int SaveState(tState *To)
-{
- Uint ip;
- __asm__ __volatile__(
- "call 1f;\n\t"
- "1f:\n\t"
- "pop %%eax"
- : "=a" (ip)
- : );
- // If we just returned
- if(!ip) return 1;
-
- To->IP = ip;
- __asm__ __volatile__ ("mov %%esp, %1" : "=r"(To->SP));
- __asm__ __volatile__ ("mov %%ebp, %1" : "=r"(To->BP));
-}
-#endif
-
extern const Uint32 * const gUI_Framebuffer;
extern void UI_SetWindowDims(int Width, int Height);
-extern void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap);
+extern void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, const Uint32 *Bitmap);
extern void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H);
extern void UI_FillBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 Value);
extern void UI_Redraw(void);
#include <vfs.h>
#include <vfs_int.h>
#include <vfs_ext.h>
+#include <threads.h>
// === CONSTANTS ===
#define MAX_KERNEL_FILES 128
{
tUserHandles *ent;
tUserHandles *cur;
- int i;
+ int i, maxhandles;
cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
if(!cur) return ; // Don't need to do anything if the current list is empty
ent = VFS_int_GetUserHandles(PID, 1);
- memcpy(ent->Handles, cur->Handles, CFGINT(CFG_VFS_MAXFILES)*sizeof(tVFS_Handle));
+ maxhandles = *Threads_GetMaxFD();
+ memcpy(ent->Handles, cur->Handles, maxhandles*sizeof(tVFS_Handle));
- for( i = 0; i < CFGINT(CFG_VFS_MAXFILES); i ++ )
+ for( i = 0; i < maxhandles; i ++ )
{
if(!cur->Handles[i].Node) continue;
- if(ent->Handles[i].Node->Reference)
- ent->Handles[i].Node->Reference(ent->Handles[i].Node);
+ if(ent->Handles[i].Node->Type->Reference)
+ ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
}
}
{
tUserHandles *ent;
int pid = Threads_GetPID();
+ int maxhandles = *Threads_GetMaxFD();
ent = VFS_int_GetUserHandles(pid, 0);
if(!ent) {
return NULL;
}
- if(FD >= CFGINT(CFG_VFS_MAXFILES)) {
- LOG("FD (%i) > Limit (%i), RETURN NULL", FD, CFGINT(CFG_VFS_MAXFILES));
+ if(FD >= maxhandles) {
+ LOG("FD (%i) > Limit (%i), RETURN NULL", FD, maxhandles);
return NULL;
}
h = &ent->Handles[ FD ];
if(bIsUser)
{
tUserHandles *ent;
+ int maxhandles = *Threads_GetMaxFD();
// Find the PID's handle list
ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
// Get a handle
- for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
+ for( i = 0; i < maxhandles; i ++ )
{
if(ent->Handles[i].Node) continue;
ent->Handles[i].Node = Node;
// === PROTOTYPES ===
int Video_Install(char **Arguments);
Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer);
int Video_IOCtl(tVFS_Node *Node, int ID, void *Data);
// --- 2D Acceleration Functions --
void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
// === GLOBALS ===
//MODULE_DEFINE(0, VERSION, NativeVideo, Video_Install, NULL, NULL);
-tDevFS_Driver gVideo_DriverStruct = {
- NULL, "NativeVideo",
- {
+tVFS_NodeType gVideo_NodeType = {
.Read = Video_Read,
.Write = Video_Write,
.IOCtl = Video_IOCtl
- }
+};
+tDevFS_Driver gVideo_DriverStruct = {
+ NULL, "NativeVideo",
+ {.Type = &gVideo_NodeType}
};
int giVideo_DriverID;
int giVideo_CurrentFormat;
/**
* \brief Write to the framebuffer
*/
-Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)
{
int i;
ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
{
case VIDEO_BUFFMT_TEXT:
{
- tVT_Char *chars = Buffer;
+ const tVT_Char *chars = Buffer;
// int pitch = giUI_Pitch;
int widthInChars = giUI_Width/giVT_CharWidth;
int heightInChars = giUI_Height/giVT_CharHeight;