OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o vfs/memfile.o vfs/nodecache.o
OBJ += vfs/fs/root.o vfs/fs/devfs.o
OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
-OBJ += drv/fifo.o drv/dma.o drv/pci.o drv/vterm.o drv/vga.o drv/kb.o
+OBJ += drv/fifo.o drv/dma.o drv/pci.o drv/kb.o drv/vga.o drv/vterm.o
OBJ += $(addprefix drv/, $(addsuffix .o,$(DRIVERS)))
OBJ := $(addsuffix .$(ARCH), $(OBJ))
MODS += $(addprefix ../Modules/, $(addsuffix .xo.$(ARCH),$(MODULES)))
}
LogF("\n");
}
+
+/**
+ * \fn void StartupPrint(char *Str)
+ */
+void StartupPrint(char *Str)
+{
+ Uint16 *buf = (void*)0xC00B8000;
+ int i = 0;
+ static int line = 0;
+ while(*Str)
+ {
+ buf[line*80 + i++] = *Str | 0x0700;
+ Str ++;
+ }
+
+ while(i < 80) buf[line*80 + i++] = 0x0720;
+
+ line ++;
+ if(line == 25)
+ {
+ line --;
+ memcpy(buf, &buf[80], 80*24*2);
+ memset(&buf[80*24], 0, 80*2);
+ }
+}
void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
// === GLOBALS ===
-MODULE_DEFINE(0, 0x0032, i386ATA, ATA_Install, NULL);
+MODULE_DEFINE(0, 0x0032, i386ATA, ATA_Install, NULL, NULL);
tDevFS_Driver gATA_DriverInfo = {
NULL, "ata",
{
* AcessOS 0.1\r
* Floppy Disk Access Code\r
*/\r
-#define DEBUG 0\r
+#define DEBUG 1\r
#include <common.h>\r
#include <modules.h>\r
#include <fs_devfs.h>\r
gFDD_Devices[0].track[0] = -1;\r
gFDD_Devices[1].track[1] = -1;\r
\r
+ Log("[FDD ] Detected Disk 0: %s and Disk 1: %s\n", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
+ \r
// Clear FDD IRQ Flag\r
FDD_SensInt(0x3F0, NULL, NULL);\r
// Install IRQ6 Handler\r
// Reset Primary FDD Controller\r
FDD_Reset(0);\r
\r
- Log("[FDD ] Detected Disk 0: %s and Disk 1: %s\n", cFDD_TYPES[data>>4], cFDD_TYPES[data&0xF]);\r
- \r
// Initialise Root Node\r
gFDD_DriverInfo.RootNode.CTime = gFDD_DriverInfo.RootNode.MTime\r
= gFDD_DriverInfo.RootNode.ATime = now();\r
int KB_IOCtl(tVFS_Node *Node, int Id, void *Data);
// === GLOBALS ===
-MODULE_DEFINE(0, 0x0100, PS2Keybard, KB_Install, NULL, NULL);
+MODULE_DEFINE(0, 0x0100, PS2Keyboard, KB_Install, NULL, NULL);
tDevFS_Driver gKB_DevInfo = {
NULL, "PS2Keyboard",
{
tVFS_Node Node;
} tVTerm;
+// === IMPORTS ===
+extern void Debug_SetKTerminal(char *File);
+
// === PROTOTYPES ===
int VT_Install(char **Arguments);
char *VT_ReadDir(tVFS_Node *Node, int Pos);
// Add to DevFS
DevFS_AddDevice( &gVT_DrvInfo );
+ // Set kernel output to VT0
+ //Debug_SetKTerminal("/Devices/VTerm/0");
+
return 0;
}
int Module_IsLoaded(char *Name);
// === IMPORTS ===
+extern void StartupPrint(char *Str);
extern tModule gKernelModules[];
-extern void gKernelModulesEnd;
+extern void gKernelModulesEnd;
// === GLOBALS ===
int giNumBuiltinModules = 0;
// === CODE ===
int Modules_LoadBuiltins()
{
- int i;
+ int i, j, k;
+ int numToInit = 0;
+ Uint8 *baIsLoaded;
+ char **deps;
+
giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
giNumBuiltinModules /= sizeof(tModule);
+ baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
+
+ // Pass 1 - Are the dependencies compiled in?
for( i = 0; i < giNumBuiltinModules; i++ )
{
- Log("Initialising %p '%s' v%i.%i...",
- &gKernelModules[i],
- gKernelModules[i].Name,
- gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
- );
- gKernelModules[i].Init(NULL);
+ deps = gKernelModules[i].Dependencies;
+ if(deps)
+ {
+ for( j = 0; deps[j]; j++ )
+ {
+ for( k = 0; k < giNumBuiltinModules; k++ ) {
+ if(strcmp(deps[j], gKernelModules[k].Name) == 0)
+ break;
+ }
+ if(k == giNumBuiltinModules) {
+ Warning("Unable to find dependency '%s' for '%s' in kernel",
+ deps[j], gKernelModules[i].Name);
+
+ baIsLoaded[i] = -1; // Don't Load
+ break;
+ }
+ }
+ }
+ numToInit ++;
+ }
+
+ // Pass 2 - Intialise
+ while(numToInit)
+ {
+ for( i = 0; i < giNumBuiltinModules; i++ )
+ {
+ if( baIsLoaded[i] ) continue; // Ignore already loaded modules
+
+ if( deps )
+ {
+ for( j = 0; deps[j]; j++ )
+ {
+ for( k = 0; k < giNumBuiltinModules; k++ ) {
+ if(strcmp(deps[j], gKernelModules[k].Name) == 0)
+ break;
+ }
+ // `k` is assumed to be less than `giNumBuiltinModules`
+
+ // If a dependency failed, skip and mark as failed
+ if( baIsLoaded[k] == -1 ) {
+ baIsLoaded[i] = -1;
+ numToInit --;
+ break;
+ }
+ // If a dependency is not intialised, skip
+ if( !baIsLoaded[k] ) break;
+ }
+ // Check if we broke out
+ if( deps[j] ) continue;
+ }
+
+ // All Dependencies OK? Initialise
+ StartupPrint(gKernelModules[i].Name);
+ Log("Initialising %p '%s' v%i.%i...",
+ &gKernelModules[i],
+ gKernelModules[i].Name,
+ gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
+ );
+ gKernelModules[i].Init(NULL);
+ // Mark as loaded
+ baIsLoaded[i] = 1;
+ numToInit --;
+ }
}
return 0;
extern int PCI_Install();
extern void DMA_Install();
extern void Debug_SetKTerminal(char *File);
+extern void StartupPrint(char *Str);
// === PROTOTYPES ===
void System_Init(char *ArgString);
void System_Init(char *ArgString)
{
// - Start Builtin Drivers & Filesystems
+ StartupPrint("Scanning PCI Bus...");
PCI_Install();
+ StartupPrint("Loading DMA...");
DMA_Install();
+ StartupPrint("Loading staticly compiled modules...");
Modules_LoadBuiltins();
// Set the debug to be echoed to the terminal
+ StartupPrint("Kernel now echoes to VT6 (Ctrl-Alt-F7)");
Debug_SetKTerminal("/Devices/VTerm/6");
// - Parse Kernel's Command Line
/**\r
* \file fs/ext2.c\r
* \brief Second Extended Filesystem Driver\r
- * \todo Implement file read support\r
+ * \todo Implement file full write support\r
*/\r
#define DEBUG 1\r
+#define VERBOSE 0\r
#include <common.h>\r
#include <vfs.h>\r
#include <modules.h>\r
disk->Groups\r
);\r
\r
- #if DEBUG\r
+ #if VERBOSE\r
LOG("Block Group 0");\r
LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);\r
LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);\r
* FAT12/16/32 Driver Version (Incl LFN)\r
*/\r
#define DEBUG 0\r
+#define VERBOSE 1\r
+\r
+#define CACHE_FAT 1 //!< Caches the FAT in memory\r
+#define USE_LFN 1 //!< Enables the use of Long File Names\r
+\r
#include <common.h>\r
#include <modules.h>\r
#include <vfs.h>\r
#include "fs_fat.h"\r
\r
-#define VERBOSE 1\r
-\r
-#define CACHE_FAT 1 //!< Caches the FAT in memory\r
-#define USE_LFN 1 //!< Enables the use of Long File Names\r
\r
// === TYPES ===\r
#if USE_LFN\r
MODULE_DEFINE(0, 0x51 /*v0.80*/, FAT32, FAT_Install, NULL, NULL);\r
tFAT_VolInfo gFAT_Disks[8];\r
int giFAT_PartCount = 0;\r
-#if CACHE_FAT\r
-Uint32 *fat_cache[8];\r
-#endif\r
#if USE_LFN\r
t_lfncache *fat_lfncache;\r
#endif\r
#if CACHE_FAT\r
{\r
Uint32 Ofs;\r
- fat_cache[ giFAT_PartCount ] = (Uint32*)malloc(sizeof(Uint32)*CountofClusters);\r
- if(fat_cache[giFAT_PartCount] == NULL) {\r
+ diskInfo->FATCache = (Uint32*)malloc(sizeof(Uint32)*CountofClusters);\r
+ if(diskInfo->FATCache == NULL) {\r
Warning("FAT_InitDisk - Heap Exhausted\n");\r
return NULL;\r
}\r
Ofs += 3*512;\r
}\r
val = *((int*)(buf+j*3));\r
- fat_cache[giFAT_PartCount][i*2] = val & 0xFFF;\r
- fat_cache[giFAT_PartCount][i*2+1] = (val>>12) & 0xFFF;\r
+ diskInfo->FATCache[i*2] = val & 0xFFF;\r
+ diskInfo->FATCache[i*2+1] = (val>>12) & 0xFFF;\r
}\r
}\r
if(diskInfo->type == FAT16) {\r
VFS_ReadAt(diskInfo->fileHandle, Ofs, 512, buf);\r
Ofs += 512;\r
}\r
- fat_cache[giFAT_PartCount][i] = buf[i&255];\r
+ diskInfo->FATCache[i] = buf[i&255];\r
}\r
}\r
if(diskInfo->type == FAT32) {\r
VFS_ReadAt(diskInfo->fileHandle, Ofs, 512, buf);\r
Ofs += 512;\r
}\r
- fat_cache[giFAT_PartCount][i] = buf[i&127];\r
+ diskInfo->FATCache[i] = buf[i&127];\r
}\r
}\r
LOG("FAT Fully Cached");\r
#endif /*CACHE_FAT*/\r
\r
//Initalise inode cache for FAT\r
- gFAT_Disks[giFAT_PartCount].inodeHandle = Inode_GetHandle();\r
- LOG("Inode Cache handle is %i", gFAT_Disks[giFAT_PartCount].inodeHandle);\r
+ diskInfo->inodeHandle = Inode_GetHandle();\r
+ LOG("Inode Cache handle is %i", diskInfo->inodeHandle);\r
\r
// == VFS Interface\r
- node = &gFAT_Disks[giFAT_PartCount].rootNode;\r
+ node = &diskInfo->rootNode;\r
node->Inode = diskInfo->rootOffset;\r
node->Size = bs->files_in_root; // Unknown - To be set on readdir\r
node->ImplInt = giFAT_PartCount;\r
}\r
\r
/**\r
- * \fn static Uint32 FAT_int_GetFatValue(int handle, Uint32 cluster)\r
+ * \fn static Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster)\r
* \brief Fetches a value from the FAT\r
*/\r
-static Uint32 FAT_int_GetFatValue(int handle, Uint32 cluster)\r
+static Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster)\r
{\r
- Uint32 val;\r
+ Uint32 val = 0;\r
+ #if !CACHE_FAT\r
+ Uint32 ofs = Disk->bootsect.resvSectCount*512;\r
+ #endif\r
ENTER("iHandle xCluster", handle, cluster);\r
#if CACHE_FAT\r
- val = fat_cache[handle][cluster];\r
+ val = Disk->FATCache[cluster];\r
#else\r
- if(gFAT_Disks[handle].type == FAT12) {\r
- VFS_ReadAt(gFAT_Disks[handle].fileHandle, 512+(cluster&~1)*3, 3, &val);\r
+ if(Disk->type == FAT12) {\r
+ VFS_ReadAt(Disk->fileHandle, ofs+(cluster>>1)*3, 3, &val);\r
val = (cluster&1 ? val&0xFFF : val>>12);\r
- } else if(gFAT_Disks[handle].type == FAT16) {\r
- VFS_ReadAt(gFAT_Disks[handle].fileHandle, 512+cluster*2, 2, &val);\r
+ } else if(Disk->type == FAT16) {\r
+ VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val);\r
} else {\r
- VFS_ReadAt(gFAT_Disks[handle].fileHandle, 512+cluster*4, 4, &val);\r
+ VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val);\r
}\r
#endif /*CACHE_FAT*/\r
LEAVE('x', val);\r
// Sanity Check offset\r
if(offset > node->Size) {\r
//LOG("Reading past EOF (%i > %i)", offset, node->Size);\r
+ LEAVE('i', 0);\r
return 0;\r
}\r
// Clamp Size\r
\r
//Skip previous clusters\r
for(i=preSkip;i--;) {\r
- cluster = FAT_int_GetFatValue(handle, cluster);\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
if(cluster == eocMarker) {\r
Warning("FAT_Read - Offset is past end of cluster chain mark");\r
}\r
return length;\r
}\r
\r
- cluster = FAT_int_GetFatValue(handle, cluster);\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
\r
#if DEBUG\r
LOG("pos=%i\n", pos);\r
FAT_int_ReadCluster(handle, cluster, bpc, tmpBuf);\r
memcpy((void*)(buffer+pos), tmpBuf, bpc);\r
pos += bpc;\r
- cluster = FAT_int_GetFatValue(handle, cluster);\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
if(cluster == eocMarker) {\r
Warning("FAT_Read - Read past End of Cluster Chain");\r
free(tmpBuf);\r
{\r
//Skip previous clusters\r
for(a=preSkip;a--;) {\r
- cluster = FAT_int_GetFatValue(dirNode->ImplInt, cluster);\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
}\r
}\r
\r
// Check for end of cluster chain\r
if((disk->type == FAT12 && cluster == EOC_FAT12)\r
|| (disk->type == FAT16 && cluster == EOC_FAT16)\r
- || (disk->type == FAT32 && cluster == EOC_FAT32))\r
+ || (disk->type == FAT32 && cluster == EOC_FAT32)) {\r
+ LEAVE('n');\r
return NULL;\r
+ }\r
\r
// Bounds Checking (Used to spot heap overflows)\r
if(cluster > disk->clusterCount + 2)\r
{\r
if( dirCluster == disk->rootOffset && disk->type != FAT32 )\r
continue;\r
- dirCluster = FAT_int_GetFatValue(node->ImplInt, dirCluster);\r
+ dirCluster = FAT_int_GetFatValue(disk, dirCluster);\r
diskOffset = (disk->firstDataSect+(dirCluster-2)*disk->bootsect.spc)*512;\r
}\r
}\r
fat_bootsect bootsect; //!< Boot Sector\r
tVFS_Node rootNode; //!< Root Node\r
int inodeHandle; //!< Inode Cache Handle\r
+ #if CACHE_FAT\r
+ Uint32 *FATCache; //!< FAT Cache\r
+ #endif\r
};\r
\r
typedef struct drv_fat_volinfo_s tFAT_VolInfo;\r
Acess2 is [TPG]'s hobby operating system.
-The Acess kernel is SEMI-posix compilant, but will be a comatability
+The Acess kernel is SEMI-posix compilant, but there will be a comatability
library that emulates the different functions.
=== Source Tree ===
/Usermode/include - Required include files for the shared libraries.
=== Building ===
+Compiling Acess is relatively simple (at the moment)
+First edit /Makefile.cfg and set the build programs (making sure they match
+ the architecture you are building for).
+Then select the architecture to build (At the moment only x86:i386 works).
+Edit the FILESYSTEMS variable to alter what filesystems are comipled in
+ (see /Kernel/vfs/fs for what filesystems are included).
+DRIVERS defines what device drivers are to be included from the Kernel
+ tree (see /Kernel/drv for a list).
+MODULES defines what modules should be statically linked with the kernel
+ (see /Modules for a list)
+
+Finally set the source root directory (ACESSDIR) and the destination
+ directory (DISTROOT) then call make in the source root.