From 1e7db40300bc594cf708bb6082a6e05a268da946 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 26 Dec 2009 11:18:13 +0800 Subject: [PATCH] Big Changes - See commit details - Cleaned up and fixed kernel API Documentation - Removed drvutil.h and moved it's definitions to tpl_drv_disk.h - Changes to the VFS and Driver specs (only minor) - Fixed behaviour of loader when a module doesn't initialise - Fixed some modules returning zero when they successfully loaded - Other changes to fix doxygen generation --- Kernel/Doxyfile.api | 8 +- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86/include/arch.h | 5 - Kernel/arch/x86/mm_virt.c | 14 +- Kernel/bin/README | 24 +++ Kernel/bin/elf.c | 22 +-- Kernel/bin/{bin_elf.h => elf.h} | 4 +- Kernel/debug.c | 23 +++ Kernel/drv/ata_x86.c | 98 +++++++++--- Kernel/drv/iocache.c | 10 +- Kernel/drv/vga.c | 3 +- Kernel/drv/vterm.c | 2 +- Kernel/drvutil.c | 2 +- Kernel/include/apidoc_mainpage.h | 62 ++++++++ Kernel/include/binary.h | 129 ++++++++++++++-- Kernel/include/common.h | 7 +- Kernel/include/drvutil.h | 23 --- Kernel/include/fs_devfs.h | 14 +- Kernel/include/fs_sysfs.h | 29 ++++ Kernel/include/tpl_drv_common.h | 82 ++++++++-- Kernel/include/tpl_drv_disk.h | 80 ++++++++++ Kernel/include/tpl_drv_keyboard.h | 73 ++++++++- Kernel/include/tpl_drv_network.h | 33 ++++- Kernel/include/tpl_drv_terminal.h | 39 +++-- Kernel/include/tpl_drv_video.h | 92 +++++++++--- Kernel/include/vfs.h | 107 ++++++++------ Kernel/include/vfs_ext.h | 238 +++++++++++++++++++++++++++--- Kernel/modules.c | 10 +- Kernel/syscalls.c | 5 +- Kernel/vfs/io.c | 16 +- Kernel/vfs/main.c | 6 +- Kernel/vfs/mount.c | 10 +- Kernel/vfs/open.c | 5 +- Makefile.cfg | 5 +- Modules/BochsGA/bochsvbe.c | 11 +- Modules/FDD/fdd.c | 162 ++++++++++++++------ Modules/NE2000/ne2000.c | 2 +- 37 files changed, 1154 insertions(+), 303 deletions(-) create mode 100644 Kernel/bin/README rename Kernel/bin/{bin_elf.h => elf.h} (95%) create mode 100644 Kernel/include/apidoc_mainpage.h delete mode 100644 Kernel/include/drvutil.h create mode 100644 Kernel/include/tpl_drv_disk.h diff --git a/Kernel/Doxyfile.api b/Kernel/Doxyfile.api index a715b6ba..7957e58d 100644 --- a/Kernel/Doxyfile.api +++ b/Kernel/Doxyfile.api @@ -14,6 +14,8 @@ # Project related configuration options #--------------------------------------------------------------------------- +LAYOUT_FILE = DoxygenLayout.xml + # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the @@ -564,7 +566,11 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = include/vfs.h include/fs_devfs.h include/iocache.h include/ +INPUT = include/apidoc_mainpage.h \ + include/binary.h \ + include/vfs.h include/vfs_ext.h \ + include/fs_devfs.h \ + include/iocache.h include/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index 05602fee..f5a0a805 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1041 +BUILD_NUM = 1068 diff --git a/Kernel/arch/x86/include/arch.h b/Kernel/arch/x86/include/arch.h index 92ccf056..77cdd706 100644 --- a/Kernel/arch/x86/include/arch.h +++ b/Kernel/arch/x86/include/arch.h @@ -77,8 +77,6 @@ typedef Uint32 tPAddr; #endif typedef Uint32 tVAddr; -typedef void (*tThreadFunction)(void*); - typedef struct { Uint gs, fs, es, ds; Uint edi, esi, ebp, kesp; @@ -135,7 +133,4 @@ typedef struct { Uint EIP, ESP, EBP; } tTaskState; -// --- Interface Flags & Macros -#define CLONE_VM 0x10 - #endif // !defined(_ARCH_H_) diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index c29db507..02bc9ac9 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -168,9 +168,9 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) if( gaPageDir[Addr>>22] & PF_PRESENT ) Log("gaPageTable[0x%x] = 0x%x", Addr>>12, gaPageTable[Addr>>12]); - MM_DumpTables(0, -1); + //MM_DumpTables(0, -1); - Panic("Page Fault at 0x%x\n", Regs->eip); + Panic("Page Fault at 0x%x (Accessed 0x%x)", Regs->eip, Addr); } /** @@ -329,16 +329,16 @@ tPAddr MM_GetPhysAddr(tVAddr Addr) /** - * \fn int MM_IsUser(tVAddr Addr) + * \fn int MM_IsUser(tVAddr VAddr) * \brief Checks if a page is user accessable */ -int MM_IsUser(tVAddr Addr) +int MM_IsUser(tVAddr VAddr) { - if( !(gaPageDir[Addr >> 22] & 1) ) + if( !(gaPageDir[VAddr >> 22] & 1) ) return 0; - if( !(gaPageTable[Addr >> 12] & 1) ) + if( !(gaPageTable[VAddr >> 12] & 1) ) return 0; - if( !(gaPageTable[Addr >> 12] & PF_USER) ) + if( !(gaPageTable[VAddr >> 12] & PF_USER) ) return 0; return 1; } diff --git a/Kernel/bin/README b/Kernel/bin/README new file mode 100644 index 00000000..63d64bb9 --- /dev/null +++ b/Kernel/bin/README @@ -0,0 +1,24 @@ +Acess2 Binary File Loader Specifcation +-------------------------------------- + +Binary file loaders are defined by creating a \a tBinaryType variable that +is registered with the kernel. + +\a tBinaryType contains seven fields. +-# \a Next + This field is used internally by the kernel and should be set to NULL + when the definition is initialise and not changed by the driver. +-# \a Ident + This field tells the kernel how to recognise this file format. If the + first 32-bits of the file (ANDed with the \a Mask field) match this + value, the file will be passed to this loader. +-# \a Mask + Determines what bits in the first 32-bits of the file matter for the + identifcation. +-# \a Name + This is a C string that uniquely identifies this binary format. +-# \a Load + This field is a pointer to a function that takes a VFS Handle of the + source exectuable file as an argument and returns a \a tBinary + pointer that defines the location and attributes of the exectable's + segments. (See \a tBinary for more information) diff --git a/Kernel/bin/elf.c b/Kernel/bin/elf.c index 745c2c7a..2f37739e 100644 --- a/Kernel/bin/elf.c +++ b/Kernel/bin/elf.c @@ -1,26 +1,14 @@ /* -Acess v0.1 -ELF Executable Loader Code -*/ + * Acess v0.1 + * ELF Executable Loader Code + */ +#define DEBUG 0 #include #include -#include "bin_elf.h" +#include "elf.h" -#define DEBUG 0 #define DEBUG_WARN 1 -#if DEBUG -# define DEBUGS(v...) Log(v) -#else -# define DEBUGS(v...) -# undef ENTER -# undef LOG -# undef LEAVE -# define ENTER(...) -# define LOG(...) -# define LEAVE(...) -#endif - // === PROTOTYPES === tBinary *Elf_Load(int fp); diff --git a/Kernel/bin/bin_elf.h b/Kernel/bin/elf.h similarity index 95% rename from Kernel/bin/bin_elf.h rename to Kernel/bin/elf.h index fbbfebc2..a2ba3945 100644 --- a/Kernel/bin/bin_elf.h +++ b/Kernel/bin/elf.h @@ -151,7 +151,7 @@ struct elf32_rela_s { }; enum { - R_386_NONE=0, // none + R_386_NONE = 0, // none R_386_32, // S+A R_386_PC32, // S+A-P R_386_GOT32, // G+A-P @@ -170,7 +170,7 @@ enum { #define ELF32_R_INFO(s,t) (((s)<<8)+((t)&0xFF)) // Takes a type and symbol index and returns an info value struct elf32_dyn_s { - Uint16 d_tag; + Uint32 d_tag; Uint32 d_val; //Also d_ptr }; diff --git a/Kernel/debug.c b/Kernel/debug.c index a23c4c41..f78ea015 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -5,19 +5,42 @@ #include #include +#define DEBUG_TO_E9 1 +#define DEBUG_TO_SERIAL 1 +#define SERIAL_PORT 0x3F8 + // === IMPORTS === extern void Threads_Dump(); // === GLOBALS === int gDebug_Level = 0; int giDebug_KTerm = -1; + int gbDebug_SerialSetup = 0; // === CODE === static void E9(char ch) { if(giDebug_KTerm != -1) VFS_Write(giDebug_KTerm, 1, &ch); + + #if DEBUG_TO_SERIAL + if(!gbDebug_SerialSetup) { + outb(SERIAL_PORT + 1, 0x00); // Disable all interrupts + outb(SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(SERIAL_PORT + 1, 0x00); // (hi byte) + outb(SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it + outb(SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + gbDebug_SerialSetup = 1; + } + while( (inb(SERIAL_PORT + 5) & 0x20) == 0 ); + outb(SERIAL_PORT, ch); + #endif + + #if DEBUG_TO_E9 __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) ); + #endif } static void E9_Str(char *Str) diff --git a/Kernel/drv/ata_x86.c b/Kernel/drv/ata_x86.c index 0c615bf9..8d9e2e85 100644 --- a/Kernel/drv/ata_x86.c +++ b/Kernel/drv/ata_x86.c @@ -2,14 +2,17 @@ * Acess2 IDE Harddisk Driver * drv/ide.c */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include #include #include #include -#include +#include + +// --- Flags --- +#define START_BEFORE_CMD 0 // === CONSTANTS === #define MAX_ATA_DISKS 4 @@ -175,15 +178,14 @@ int ATA_Install() int ATA_SetupIO() { int ent; - Uint addr; + tPAddr addr; ENTER(""); // Get IDE Controller's PCI Entry ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1); - LOG("ent = %i\n", ent); + LOG("ent = %i", ent); gATA_BusMasterBase = PCI_GetBAR4( ent ); - LOG("gATA_BusMasterBase = 0x%x\n", gATA_BusMasterBase); if( gATA_BusMasterBase == 0 ) { Warning("It seems that there is no Bus Master Controller on this machine, get one"); LEAVE('i', 0); @@ -195,6 +197,11 @@ int ATA_SetupIO() gATA_BusMasterBasePtr = (void*)(0xC0000000|gATA_BusMasterBase); else gATA_BusMasterBasePtr = (void*)( MM_MapHWPage( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) ); + LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr); + } + else { + // Bit 0 is left set as a flag to other functions + LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1); } IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri ); @@ -203,13 +210,18 @@ int ATA_SetupIO() gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[0] ); gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[1] ); - LOG("gATA_PRDTs = {0x%x, 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr); + LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr); addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[0] ); + LOG("addr = 0x%x", addr); ATA_int_BusMasterWriteDWord(4, addr); addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[1] ); + LOG("addr = 0x%x", addr); ATA_int_BusMasterWriteDWord(12, addr); + outb(IDE_PRI_BASE+1, 1); + outb(IDE_SEC_BASE+1, 1); + LEAVE('i', 1); return 1; } @@ -275,8 +287,12 @@ int ATA_ScanDisk(int Disk) int i; tVFS_Node *node; + ENTER("iDisk", Disk); + base = ATA_GetBasePort( Disk ); + LOG("base = 0x%x", base); + // Send Disk Selector if(Disk == 1 || Disk == 3) outb(base+6, 0xB0); @@ -286,12 +302,18 @@ int ATA_ScanDisk(int Disk) // Send IDENTIFY outb(base+7, 0xEC); val = inb(base+7); // Read status - if(val == 0) return 0; // Disk does not exist + if(val == 0) { + LEAVE('i', 0); + return 0; // Disk does not exist + } // Poll until BSY clears and DRQ sets or ERR is set while( ((val & 0x80) || !(val & 0x08)) && !(val & 1)) val = inb(base+7); - if(val & 1) return 0; // Error occured, so return false + if(val & 1) { + LEAVE('i', 0); + return 0; // Error occured, so return false + } // Read Data for(i=0;i<256;i++) buf[i] = inw(base); @@ -303,6 +325,8 @@ int ATA_ScanDisk(int Disk) gATA_Disks[ Disk ].Sectors = identify->Sectors28; + LOG("gATA_Disks[ Disk ].Sectors = 0x%x", gATA_Disks[ Disk ].Sectors); + if( gATA_Disks[ Disk ].Sectors / (2048*1024) ) Log("Disk %i: 0x%llx Sectors (%i GiB)", Disk, gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / (2048*1024)); @@ -333,6 +357,7 @@ int ATA_ScanDisk(int Disk) // --- Scan Partitions --- + LOG("Reading MBR"); // Read Boot Sector ATA_ReadDMA( Disk, 0, 1, mbr ); @@ -342,6 +367,7 @@ int ATA_ScanDisk(int Disk) else // No? Just parse the MBR ATA_ParseMBR(Disk); + LEAVE('i', 0); return 1; } @@ -364,6 +390,8 @@ void ATA_ParseMBR(int Disk) tMBR mbr; Uint64 extendedLBA; + ENTER("iDisk", Disk); + // Read Boot Sector ATA_ReadDMA( Disk, 0, 1, &mbr ); @@ -379,6 +407,7 @@ void ATA_ParseMBR(int Disk) ) { if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) { + LOG("Extended Partition"); if(extendedLBA != 0) { Warning("Disk %i has multiple extended partitions, ignoring rest", Disk); continue; @@ -386,6 +415,7 @@ void ATA_ParseMBR(int Disk) extendedLBA = mbr.Parts[i].LBAStart; continue; } + LOG("Primary Partition"); gATA_Disks[Disk].NumPartitions ++; continue; @@ -433,6 +463,7 @@ void ATA_ParseMBR(int Disk) } } } + LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions); // Create patition array gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) ); @@ -441,6 +472,7 @@ void ATA_ParseMBR(int Disk) extendedLBA = 0; for( i = 0; i < 4; i ++ ) { + Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID); if( mbr.Parts[i].SystemID == 0 ) continue; if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) // LBA 28 { @@ -567,6 +599,8 @@ void ATA_ParseMBR(int Disk) } } } + + LEAVE('-'); } /** @@ -631,7 +665,11 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name) if(Name[0] < 'A' || Name[0] > 'A'+MAX_ATA_DISKS) return NULL; // Raw Disk - if(Name[1] == '\0') return &gATA_Disks[Name[0]-'A'].Node; + if(Name[1] == '\0') { + if( gATA_Disks[Name[0]-'A'].Sectors == 0 ) + return NULL; + return &gATA_Disks[Name[0]-'A'].Node; + } // Partitions if(Name[1] < '0' || '9' < Name[1]) return NULL; @@ -805,8 +843,15 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) int disk = Disk & 1; Uint16 base; + ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer); + // Check if the count is small enough - if(Count > MAX_DMA_SECTORS) return 0; + if(Count > MAX_DMA_SECTORS) { + Warning("Passed too many sectors for a bulk DMA read (%i > %i)", + Count, MAX_DMA_SECTORS); + LEAVE('i'); + return 0; + } // Get exclusive access to the disk controller LOCK( &giaATA_ControllerLock[ cont ] ); @@ -817,6 +862,9 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) // Get Port Base base = ATA_GetBasePort(Disk); + // Reset IRQ Flag + gaATA_IRQs[cont] = 0; + // Set up transfer outb(base+0x01, 0x00); if( Address > 0x0FFFFFFF ) // Use LBA48 @@ -836,29 +884,44 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) outb(base+0x03, (Uint8) Address); // Low Addr outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr outb(base+0x05, (Uint8) (Address >> 16)); // High Addr + + LOG("Starting Transfer"); + #if START_BEFORE_CMD + // Start transfer + ATA_int_BusMasterWriteByte( cont << 3, 9 ); // Read and start + if( Address > 0x0FFFFFFF ) + outb(base+0x07, HDD_DMA_R48); // Read Command (LBA48) + else + outb(base+0x07, HDD_DMA_R28); // Read Command (LBA28) + #else if( Address > 0x0FFFFFFF ) outb(base+0x07, HDD_DMA_R48); // Read Command (LBA48) else outb(base+0x07, HDD_DMA_R28); // Read Command (LBA28) - - // Reset IRQ Flag - gaATA_IRQs[cont] = 0; - // Start transfer ATA_int_BusMasterWriteByte( cont << 3, 9 ); // Read and start + #endif // Wait for transfer to complete - while( gaATA_IRQs[cont] == 0 ) Threads_Yield(); + //ATA_int_BusMasterWriteByte( (cont << 3) + 2, 0x4 ); + while( gaATA_IRQs[cont] == 0 ) { + //Uint8 val = ATA_int_BusMasterReadByte( (cont << 3) + 2, 0x4 ); + //LOG("val = 0x%02x", val); + Threads_Yield(); + } // Complete Transfer ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop + LOG("Transfer Completed & Acknowledged"); + // Copy to destination buffer memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE ); // Release controller lock RELEASE( &giaATA_ControllerLock[ cont ] ); + LEAVE('i', 1); return 1; } @@ -937,8 +1000,9 @@ void ATA_IRQHandlerPri(int unused) // IRQ bit set for Primary Controller val = ATA_int_BusMasterReadByte( 0x2 ); + LOG("IRQ val = 0x%x", val); if(val & 4) { - //Log(" ATA_IRQHandlerPri: IRQ hit (val = 0x%x)", val); + LOG("IRQ hit (val = 0x%x)", val); ATA_int_BusMasterWriteByte( 0x2, 4 ); gaATA_IRQs[0] = 1; return ; @@ -954,7 +1018,7 @@ void ATA_IRQHandlerSec(int unused) // IRQ bit set for Secondary Controller val = ATA_int_BusMasterReadByte( 0xA ); if(val & 4) { - //Log(" ATA_IRQHandlerSec: IRQ hit (val = 0x%x)", val); + LOG("IRQ hit (val = 0x%x)", val); ATA_int_BusMasterWriteByte( 0xA, 4 ); gaATA_IRQs[1] = 1; return ; diff --git a/Kernel/drv/iocache.c b/Kernel/drv/iocache.c index 8ea6929a..21079cc3 100644 --- a/Kernel/drv/iocache.c +++ b/Kernel/drv/iocache.c @@ -4,6 +4,7 @@ * * By thePowersGang (John Hodge) */ +#define DEBUG 0 #include #include @@ -77,14 +78,19 @@ int IOCache_Read( tIOCache *Cache, Uint64 Sector, void *Buffer ) { tIOCache_Ent *ent; + ENTER("pCache XSector pBuffer", Cache, Sector, Buffer); + // Sanity Check! - if(!Cache || !Buffer) + if(!Cache || !Buffer) { + LEAVE('i', -1); return -1; + } // Lock LOCK( &Cache->Lock ); if(Cache->CacheSize == 0) { RELEASE( &Cache->Lock ); + LEAVE('i', -1); return -1; } @@ -96,6 +102,7 @@ int IOCache_Read( tIOCache *Cache, Uint64 Sector, void *Buffer ) memcpy(Buffer, ent->Data, Cache->SectorSize); ent->LastAccess = now(); RELEASE( &Cache->Lock ); + LEAVE('i', 1); return 1; } // It's a sorted list, so as soon as we go past `Sector` we know @@ -104,6 +111,7 @@ int IOCache_Read( tIOCache *Cache, Uint64 Sector, void *Buffer ) } RELEASE( &Cache->Lock ); + LEAVE('i', 0); return 0; } diff --git a/Kernel/drv/vga.c b/Kernel/drv/vga.c index 015423de..4c85631f 100644 --- a/Kernel/drv/vga.c +++ b/Kernel/drv/vga.c @@ -90,8 +90,7 @@ int VGA_IOCtl(tVFS_Node *Node, int Id, void *Data) case DRV_IOCTL_VERSION: *(int*)Data = 50; return 1; case DRV_IOCTL_LOOKUP: return 0; - case VIDEO_IOCTL_GETMODE: return 0; // Mode 0 only - case VIDEO_IOCTL_SETMODE: return 0; // Ignored (Text Only ATM) + case VIDEO_IOCTL_GETSETMODE: return 0; // Mode 0 only case VIDEO_IOCTL_FINDMODE: return 0; // Text Only! case VIDEO_IOCTL_MODEINFO: if( ((tVideo_IOCtl_Mode*)Data)->id != 0) return 0; diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index 575d71f9..4095feb7 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -425,7 +425,7 @@ void VT_SetTerminal(int ID) modeNum = mode.id; gVT_Terminals[ ID ].RealWidth = mode.width; gVT_Terminals[ ID ].RealHeight = mode.height; - VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETMODE, &modeNum ); + VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &modeNum ); // Update current terminal ID Log("Changed terminal from %i to %i", giVT_CurrentTerminal, ID); diff --git a/Kernel/drvutil.c b/Kernel/drvutil.c index c40a5d24..0af88b34 100644 --- a/Kernel/drvutil.c +++ b/Kernel/drvutil.c @@ -4,7 +4,7 @@ */ #define DEBUG 0 #include -#include +#include // === CODE === Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, diff --git a/Kernel/include/apidoc_mainpage.h b/Kernel/include/apidoc_mainpage.h new file mode 100644 index 00000000..f2da43a4 --- /dev/null +++ b/Kernel/include/apidoc_mainpage.h @@ -0,0 +1,62 @@ +/** + * \file apidoc_mainpage.h + * \brief API Documentation Home Page + * \author John Hodge (thePowersGang) + */ + +/** + * \mainpage Acess 2 Kernel API Documentation + * + * \section intro Introduction + * These documents attempt to describe the standard Acess 2 (and hopefully + * future versions) Kernel mode API. + * The documentation covers filesystem drivers, binary formats and the + * various device driver interface standards. + * + * \section VFS + * The core of Acess is the VFS, or Virtual File System. The VFS abstracts + * away from the user the differences between different filesystems, + * network protocols and types of hardware. + * The core of the VFS is the concept of a VFS Node (represented by the + * ::tVFS_Node type). A node defines a file (either a normal file, directory + * or some device abstraction), it's attributes (size, flags, timestamps) + * and the functions used to access and modify it. + * + * \subsection filesystems Filesystem Drivers + * Acess filesystems register themselves with the VFS by calling + * ::VFS_AddDriver with a ::tVFS_Driver structure that defines the driver's + * name, flags and mount function. + * Filesystem drivers take the + * + * \section binfmt Binary Formats + * See binary.h + * + * \section drivers Device Drivers + * All Acess2 device drivers communicate with user-level (and other parts + * of the greater kernel) via the VFS. They register themselves in a similar + * way to how filesystem drivers do, however instead of registering with + * the VFS core, they register with a special filesystem driver called the + * DevFS (fs_devfs.h). DevFS exports the ::DevFS_AddDevice function that + * takes a ::tDevFS_Driver structure as an agument that defines the + * driver's name and the VFS node of it's root. This root is used to + * provide the user access to the driver's function via IOCtl calls and + * by Read/Write calls. Drivers are also able to expose a readonly buffer + * by using ProcDev, usually to provide state information (such as usage + * statistics and other misc information) + * + * The device driver interfaces are all based on the core specifcation + * in tpl_drv_common.h (Common Device Driver definitions). + * The following subsections define the various specific types of driver + * interfaces. These definitions only define the bare minimum of what the + * driver must implement, if the driver author so wants to, they can add + * IOCtl calls and/or files (where allowed by the type specifcation) to + * their device's VFS layout. + * + * \subsection drv_video Video Devices + * Video drivers are based on a framebuffer model (unless in 3D mode, + * which is not yet fully standardised, so should be ignored). + * The driver will contain only one VFS node, that exposes the video + * framebuffer (this may not be the true framebuffer, to allow for double-buffering) + * to the user. See the full documentation in tpl_drv_video.h for the + * complete specifcation. + */ diff --git a/Kernel/include/binary.h b/Kernel/include/binary.h index e02fc2dc..ed163bd0 100644 --- a/Kernel/include/binary.h +++ b/Kernel/include/binary.h @@ -1,41 +1,144 @@ -/* +/** + * \file binary.h + * \brief Binary Loader Definitions + * \author John Hodge (thePowersGang) */ #ifndef _BINARY_H #define _BINARY_H // === TYPES === /** - * \struct sBinary * \brief Defines a binary file + * + * This structure defines and maintains the state of a binary during and + * after loading. + * Before the binary is loaded into memory (when it has just been returned + * from tBinaryType.Load) the \a Pages array will contain the file offsets + * to the page data in the \a Physical fields (or -1 for uninitialised + * data) and the \a Size fields define how much data is stored in-file + * for the page (to allow partial pages to be loaded from disk) + * Once the binary is loaded (NOTE: Drivers do not need to know about this, + * it is here for information only) the \a Physical fields now contain the + * physical addresses of the pages filled with the data. The \a Virtual + * fields contain the preferred virtual address of the pages (a given + * process may have these pages mapped to a different location). */ -typedef struct sBinary { - struct sBinary *Next; +typedef struct sBinary +{ + struct sBinary *Next; //!< Pointer used by the kernel + /** + * \brief True path of the file + * \note Used to uniquely identify the loaded binary to reduce in-memory + * duplication. + */ char *TruePath; + /** + * \brief Interpreter used to load the file + * \note This can be either requested by the individual file, or a per-driver option + */ char *Interpreter; + /** + * \brief Entrypoint of the binary (at requested base); + */ Uint Entry; + /** + * \brief File's requested load base + */ Uint Base; - int NumPages; + /** + * \brief Number of times this binary has been mapped + */ int ReferenceCount; + /** + * \brief Number of pages defined in the file + */ + int NumPages; + /** + * \brief Array of pages defined by this binary + * \note Contains \a NumPages entries + */ struct { - Uint Physical; - Uint Virtual; - Uint16 Size, Flags; + /** + * \brief Physical address, or file offset + * + * Physical address of this page or, when the file is not yet + * loaded, this is a file offset (or -1 for uninitialised data) + */ + tPAddr Physical; + tVAddr Virtual; //!< Virtual load address + Uint16 Size; //!< Number of bytes to load from the file + Uint16 Flags; //!< Load Flags } Pages[]; -} tBinary; +} tBinary; /** - * \struct sBinaryType + * \brief Binary type definition + * + * This structure is used to define a loader for a specific binary type + * so that the kernel's core binary loader can understand that type. + * The tBinaryType.Relocate and tBinaryType.GetSymbol need only be non-NULL + * if the binary type is to be used for kernel modules, otherwise it will + * only be able to load binaries for user space. */ -typedef struct sBinaryType { +typedef struct sBinaryType +{ + /** + * \brief Pointer used by the kernel + * \note Should not be touched by the driver (initialise to NULL) + */ struct sBinaryType *Next; + /** + * \brief Identifying DWord + * + * If he first 32-bits of the file match this value (when ANDed with + * tBinaryType.Mask), this binary loader will be used to load the file. + */ Uint32 Ident; - Uint32 Mask; - char *Name; + Uint32 Mask; //!< Mask value for tBinaryType.Ident + char *Name; //!< Name of this executable type (for debug purpouses) + /** + * \brief Read a binary from a file + * \param FD VFS File handle to file to load + * \return Pointer to a ::tBinary that describes how to load the file + * + * This function reads a binary file and returns a ::tBinary pointer + * that tells the core binary loader how to read the data from the file + * and where to map it to. + */ tBinary *(*Load)(int FD); + + /** + * \brief Prepares a mapped binary for execution at this address + * \param Base Binary loaded in memory + * \return Boolean Success + * \note This pointer can be NULL, but then the binary cannot be used + * to load a kernel module. + * + * tBinaryType.Relocate takes a binary that was loaded according to + * tBinaryType.Load and prepares it to run at the address it is + * loaded to, attempting to satisfy any external unresolved symbols + * required, if a symbol cannot be located, the function will return + * zero. + */ int (*Relocate)(void *Base); + + /** + * \brief Gets a symbol's address from a loaded binary + * \note The binary pointed to by \a Base may not have been through + * tBinaryType.Relocate at this time, so the driver should + * accomodate this. + */ int (*GetSymbol)(void *Base, char *Name, Uint *Dest); } tBinaryType; +/** + * \brief Registers an interpreter path with the binary loader + * \param Path Path to the requested interpreter (need not be a "true" path) + * \return Pointer to the cached string + * + * Speeds up checking if the intepreter is loaded in the kernel by allowing + * the search to use pointer comparisons instead of string comparisons. + */ extern char *Binary_RegInterp(char *Path); #endif diff --git a/Kernel/include/common.h b/Kernel/include/common.h index 7888a7aa..34825044 100644 --- a/Kernel/include/common.h +++ b/Kernel/include/common.h @@ -60,6 +60,11 @@ enum eConfigs { /** * \} */ +// --- Interface Flags & Macros +#define CLONE_VM 0x10 + +// === Types === +typedef void (*tThreadFunction)(void*); // === Kernel Export Macros === /** @@ -159,7 +164,7 @@ extern int MM_Map(tVAddr VAddr, tPAddr PAddr); /** * \brief Get the physical address of \a VAddr * \param VAddr Address of the page to get the physical address of - * \return Physical page mapped at \A VAddr + * \return Physical page mapped at \a VAddr */ extern tPAddr MM_GetPhysAddr(tVAddr VAddr); /** diff --git a/Kernel/include/drvutil.h b/Kernel/include/drvutil.h deleted file mode 100644 index b653fdcf..00000000 --- a/Kernel/include/drvutil.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Acess2 - * Common Driver/Filesystem Helper Functions - */ - -#ifndef _DRVUTIL_H_ -#define _DRVUTIL_H_ - -#include - -// === TYPES === -typedef Uint (*tDrvUtil_Callback)(Uint64 Address, Uint Count, void *Buffer, Uint Argument); - -// === PROTOTYPES === -// --- Block IO Helpers --- -extern Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, - tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument); - -extern Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, void *Buffer, - tDrvUtil_Callback ReadBlocks, tDrvUtil_Callback WriteBlocks, - Uint64 BlockSize, Uint Argument); - -#endif diff --git a/Kernel/include/fs_devfs.h b/Kernel/include/fs_devfs.h index add3eeb7..54f4280d 100644 --- a/Kernel/include/fs_devfs.h +++ b/Kernel/include/fs_devfs.h @@ -1,11 +1,7 @@ -/* - * Acess 2 - * Device Filesystem (DevFS) - * - vfs/fs/devfs.c - */ /** * \file fs_devfs.h * \brief Acess Device Filesystem interface + * \author John Hodge (thePowersGang) */ #ifndef _FS_DEVFS_H #define _FS_DEVFS_H @@ -13,11 +9,12 @@ // === TYPES === /** - * \brief DevFS Driver + * \brief DevFS driver definition */ -typedef struct sDevFS_Driver { +typedef struct sDevFS_Driver +{ struct sDevFS_Driver *Next; //!< Set to NULL by drivers (used internally) - char *Name; //!< Name of the driver file/folder + char *Name; //!< Name of the driver file/folder (must be unique) tVFS_Node RootNode; //!< Root node of driver } tDevFS_Driver; @@ -26,6 +23,7 @@ typedef struct sDevFS_Driver { * \fn int DevFS_AddDevice(tDevFS_Driver *Dev) * \brief Registers a device in the Device filesystem * \param Dev Pointer to a persistant structure that represents the driver + * \return Boolean success */ extern int DevFS_AddDevice(tDevFS_Driver *Dev); diff --git a/Kernel/include/fs_sysfs.h b/Kernel/include/fs_sysfs.h index 61a6d48b..698646f4 100644 --- a/Kernel/include/fs_sysfs.h +++ b/Kernel/include/fs_sysfs.h @@ -2,11 +2,40 @@ * Acess2 * - SysFS Export Header */ +/** + * \file fs_sysfs.h + * \brief ProcDev/SysFS Interface + * \author John Hodge (thePowersGang) + * + * + */ #ifndef _FS_SYSFS_H_ #define _FS_SYSFS_H_ +/** + * \brief Registers a file in the SysFS tree + * \param Path Path relative to the SysFS root (no .. or .) + * \param Data File buffer address + * \param Length Length of the file buffer + * \return An ID number to refer to the file, or -1 on error + * \note \a Data must be maintained until ::SysFS_UpdateFile is called + * with a different buffer, or ::SysFS_RemoveFile is called. + */ extern int SysFS_RegisterFile(char *Path, char *Data, int Length); + +/** + * \brief Updates the size/pointer associated with a SysFD file + * \param ID Number returned by ::SysFS_Register + * \param Data New buffer address + * \param Length New length of the file + * \return Boolean Success + */ extern int SysFS_UpdateFile(int ID, char *Data, int Length); + +/** + * \brief Removes a file from the SysFS tree + * \param ID Number returned by ::SysFS_Register + */ extern int SysFS_RemoveFile(int ID); #endif diff --git a/Kernel/include/tpl_drv_common.h b/Kernel/include/tpl_drv_common.h index e1bdd3e0..f20539a9 100644 --- a/Kernel/include/tpl_drv_common.h +++ b/Kernel/include/tpl_drv_common.h @@ -1,10 +1,35 @@ -/* - * Acess2 - * - Common Driver Interface - */ /** * \file tpl_drv_common.h * \brief Common Driver Interface Definitions + * \author John Hodge (thePowersGang) + * + * \section Introduction + * There are two ways Acess drivers can communicate with userspace + * applications, both are through the VFS. The first is by exposing a + * device as a file buffer, the second is by sending commands via the + * ioctl() system call. + * All drivers in Acess must at least conform to the specifcation in this + * file (even if it is just implementing eTplDrv_IOCtl.DRV_IOCTL_TYPE and + * returning eTplDrv_Type.DRV_TYPE_NULL, however, doing so is discouraged) + * + * \section ioctls Core IOCtl calls + * As said, the core Acess driver specifcation defines specific IOCtl calls + * that all drivers should implement. The four core IOCtls (defined in + * ::eTplDrv_IOCtl) allow another binary (wether it be a user-mode application + * or another driver) to tell what type of device a driver provides, the + * basic identifcation of the driver (4 character ID and BCD version number) + * and be able to use externally standardised calls that may not have + * standardised call numbers. + * NOTE: All ioctl calls WILL return -1 if the driver ran into an error + * of its own fault while executing the call. If the user was at fault + * (e.g. by passing a bad buffer) the call will return -2. + * + * \section types Driver Types + * When the eTplDrv_IOCtl.DRV_IOCTL_TYPE call is made, the driver should + * return the relevant entry in the ::eTplDrv_Type enumeration that describes + * what sub-specifcation (and hence, what device type) it implements. + * These device types are described in their own files, which are liked + * from their entries in ::eTplDrv_Type. */ #ifndef _TPL_COMMON_H #define _TPL_COMMON_H @@ -14,16 +39,47 @@ * \brief Common IOCtl Calls */ enum eTplDrv_IOCtl { - /// \brief Driver Type - Return an ::eTplDrv_Type value + /** + * ioctl(...) + * \brief Get driver type + * \return The relevant entry from ::eTplDrv_Type + */ DRV_IOCTL_TYPE, - /// \brief Get driver identifier - (char *dest[4]) + + /** + * ioctl(..., char *dest[4]) + * \brief Get driver identifier string + * \return 0 on no error + * + * This call sets the 4-byte array \a dest to the drivers 4-byte + * identifier. This identifier must be unique to the driver series. + */ DRV_IOCTL_IDENT, - /// \brief Get driver version - (int *ver) + + /** + * ioctl(...) + * \brief Get driver version number + * \return 24-bit BCD version number (2.2) + * + * This call returns the 6-digit (2 major, 2 minor, 2 patch) version number + * of the driver. + */ DRV_IOCTL_VERSION, - /// \brief Get a IOCtl from a symbolic name + + /** + * ioctl(..., char *name) + * \brief Get a IOCtl call ID from a symbolic name + * \return ID number of the call, or 0 if not found + * + * This call allows user applications to not need to know the ID numbers + * of this driver's IOCtl calls by taking a string and returning the + * IOCtl call number associated with that method name. + */ DRV_IOCTL_LOOKUP }; +//! \brief eTplDrv_IOCtl.DRV_IOCTL_LOOKUP names for the core IOCtls +//! These are the official lookup names of the core calls #define DRV_IOCTLNAMES "type", "ident", "version", "lookup" /** @@ -33,14 +89,14 @@ enum eTplDrv_IOCtl { enum eTplDrv_Type { DRV_TYPE_NULL, //!< NULL Type - Custom Interface DRV_TYPE_MISC, //!< Miscelanious Compilant - Supports the core calls - DRV_TYPE_TERMINAL, //!< Terminal - DRV_TYPE_VIDEO, //!< Video - LFB + DRV_TYPE_TERMINAL, //!< Terminal - see tpl_drv_terminal.h + DRV_TYPE_VIDEO, //!< Video - see tpl_drv_video.h DRV_TYPE_SOUND, //!< Audio - DRV_TYPE_DISK, //!< Disk - DRV_TYPE_KEYBOARD, //!< Keyboard + DRV_TYPE_DISK, //!< Disk - see tpl_drv_disk.h + DRV_TYPE_KEYBOARD, //!< Keyboard - see tpl_drv_keyboard.h DRV_TYPE_MOUSE, //!< Mouse DRV_TYPE_JOYSTICK, //!< Joystick / Gamepad - DRV_TYPE_NETWORK //!< Network Device + DRV_TYPE_NETWORK //!< Network Device - see tpl_drv_network.h }; #endif diff --git a/Kernel/include/tpl_drv_disk.h b/Kernel/include/tpl_drv_disk.h new file mode 100644 index 00000000..d459aced --- /dev/null +++ b/Kernel/include/tpl_drv_disk.h @@ -0,0 +1,80 @@ +/** + * \file tpl_drv_disk.h + * \brief Disk Driver Interface Definitions + * \author John Hodge (thePowersGang) + * + * \section dirs VFS Layout + * Disk drivers have a flexible directory layout. The root directory can + * contain subdirectories, with the only conditions being that all nodes + * must support ::eTplDrv_IOCtl with DRV_IOCTL_TYPE returning DRV_TYPE_DISK. + * And all file nodes representing disk devices (or partitions) and implemeting + * ::eTplDisk_IOCtl fully + * + * \section files Files + * When a read or write occurs on a normal file in the disk driver it will + * read/write the represented device. The accesses need not be aligned to + * the block size, however aligned reads/writes should be handled specially + * to improve speed (this can be aided by using ::DrvUtil_ReadBlock and + * ::DrvUtil_WriteBlock) + */ +#ifndef _TPL_DRV_DISK_H +#define _TPL_DRV_DISK_H + +#include + +/** + * \enum eTplDisk_IOCtl + * \brief Common Disk IOCtl Calls + * \extends eTplDrv_IOCtl + */ +enum eTplDisk_IOCtl { + /** + * ioctl(..., void) + * \brief Get the block size + * \return Size of a hardware block for this device + */ + DISK_IOCTL_GETBLOCKSIZE = 4 +}; + +/** + * \brief IOCtl name strings + */ +#define DRV_DISK_IOCTLNAMES "get_block_size" + +/** + * \brief Callback function type used by DrvUtil_ReadBlock and DrvUtil_WriteBlock + * \param Address Zero based block number to read + * \param Count Number of blocks to read + * \param Buffer Destination for read blocks + * \param Argument Argument provided in ::DrvUtil_ReadBlock and ::DrvUtil_WriteBlock + */ +typedef Uint (*tDrvUtil_Callback)(Uint64 Address, Uint Count, void *Buffer, Uint Argument); + +/** + * \brief Reads a range from a block device using aligned reads + * \param Start Base byte offset + * \param Length Number of bytes to read + * \param Buffer Destination for read data + * \param ReadBlocks Callback function to read a sequence of blocks + * \param BlockSize Size of an individual block + * \param Argument An argument to pass to \a ReadBlocks + * \return Number of bytes read + */ +extern Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, + tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument); +/** + * \brief Writes a range to a block device using aligned writes + * \param Start Base byte offset + * \param Length Number of bytes to write + * \param Buffer Destination for read data + * \param ReadBlocks Callback function to read a sequence of blocks + * \param WriteBlocks Callback function to write a sequence of blocks + * \param BlockSize Size of an individual block + * \param Argument An argument to pass to \a ReadBlocks and \a WriteBlocks + * \return Number of bytes written + */ +extern Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, void *Buffer, + tDrvUtil_Callback ReadBlocks, tDrvUtil_Callback WriteBlocks, + Uint64 BlockSize, Uint Argument); + +#endif diff --git a/Kernel/include/tpl_drv_keyboard.h b/Kernel/include/tpl_drv_keyboard.h index e94a1867..8f4c1585 100644 --- a/Kernel/include/tpl_drv_keyboard.h +++ b/Kernel/include/tpl_drv_keyboard.h @@ -1,7 +1,13 @@ /** * \file tpl_drv_keyboard.h * \brief Keyboard Driver Interface Definitions -*/ + * \author John Hodge (thePowersGang) + * + * \section dirs VFS Layout + * Keyboard drivers consist of only a single node, which is a normal file + * node with a size of zero. All reads and writes to this node are ignored + * (tVFS_Node.Read and tVFS_Node.Write are NULL) + */ #ifndef _TPL_KEYBOARD_H #define _TPL_KEYBOARD_H @@ -13,27 +19,69 @@ * \extends eTplDrv_IOCtl */ enum eTplKeyboard_IOCtl { - //! \brief Get/Set Repeat Rate - (int Rate) + /** + * ioctl(..., int *Rate) + * \brief Get/Set Repeat Rate + * \param Rate New repeat rate (pointer) + * \return Current/New Repeat rate + * + * Gets/Set the repeat rate (actually the time in miliseconds between + * repeats) of a held down key. + * If the rate is set to zero, repeating will be disabled. + */ KB_IOCTL_REPEATRATE = 4, - //! \brief Get/Set Repeat Delay - (int Delay) + + /** + * ioctl(..., int *Delay) + * \brief Get/Set Repeat Delay + * \param Delay New repeat delay (pointer) + * \return Current/New repeat delay + * + * Gets/Set the time in miliseconds before a key starts repeating + * after a key is pressed. + * Setting the delay to a negative number will cause the function to + * return -1 + */ KB_IOCTL_REPEATDELAY, - //! \brief Sets the callback + + + /** + * ioctl(..., tKeybardCallback *Callback) + * \brief Sets the callback + * \note Can be called from kernel mode only + * + * Sets the function to be called when a key event occurs (press, release + * or repeat). This function pointer must be in kernel mode (although, + * kernel->user or kernel->ring3driver abstraction functions can be used) + */ KB_IOCTL_SETCALLBACK }; /** * \brief Callback type for KB_IOCTL_SETCALLBACK + * \param Key Unicode character code for the pressed key (with bit 31 + * set if the key is released) */ typedef void (*tKeybardCallback)(Uint32 Key); /** * \brief Symbolic key codes + * + * These key codes represent non-pritable characters and are placed above + * the Unicode character space. + * If the using driver recieves a key code with the 31st bit set, it means + * that that key has been released. */ enum eTplKeyboard_KeyCodes { - KEY_ESC = 0x1B, + KEY_ESC = 0x1B, //!< Escape Character - KEY_NP_MASK = 0x40000000, //End of ASCII Range + KEY_NP_MASK = 0x40000000, //! Mask for non-printable characters + /** + * \name Special Keys + * \brief These keys are usually used on their own + * \{ + */ KEY_CAPSLOCK, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, @@ -46,14 +94,23 @@ enum eTplKeyboard_KeyCodes { KEY_KPHOME, KEY_KPUP, KEY_KPPGUP, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT, KEY_KPEND, KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL, KEY_WIN, KEY_MENU, + /** + * \} + */ // Modifiers + /** + * \name Modifiers + * \brief These keye usually alter the character stream sent to the user + * \{ + */ KEY_MODIFIERS = 0x60000000, KEY_LCTRL, KEY_RCTRL, KEY_LALT, KEY_RALT, KEY_LSHIFT, KEY_RSHIFT, - - KEY_KEYUP = 0xFF + /** + * \} + */ }; diff --git a/Kernel/include/tpl_drv_network.h b/Kernel/include/tpl_drv_network.h index 5a702a2e..6b7493ac 100644 --- a/Kernel/include/tpl_drv_network.h +++ b/Kernel/include/tpl_drv_network.h @@ -1,7 +1,31 @@ /** * \file tpl_drv_network.h * \brief Network Interface Driver Interface Definitions -*/ + * + * \section dirs VFS Layout + * All network drivers must have the following basic VFS structure + * The root of the driver will only contain files that are named from zero + * upwards that represent the present network adapters that this driver + * controls. All VFS nodes must implement ::eTplDrv_IOCtl with + * DRV_IOCTL_TYPE returning DRV_TYPE_NETWORK. + * The adapter nodes must also implement ::eTplNetwork_IOCtl fully + * (unless it is noted in the ::eTplNetwork_IOCtl documentation that a + * call is optional) + * + * \section files Adapter Files + * \subsection Reading + * When an adapter file is read from, the driver will block the reading + * thread until a packet arrives (if there is not already an unhandled + * packet in the queue) this will then be read into the destination buffer. + * If the packet does not fit in the buffer, the end of it is discarded. + * Likewise, if the packet does not completely fill the buffer, the call + * will still read to the buffer and then return the size of the packet. + * \subsection Writing + * When an adapter is written to, the data written is encoded as a packet + * and sent, if the data is not the correct size to be sent (if the packet + * is too small, or if it is too large) -1 should be returned and the packet + * will not be sent. + */ #ifndef _TPL_NETWORK_H #define _TPL_NETWORK_H @@ -16,10 +40,17 @@ enum eTplNetwork_IOCtl { /** * ioctl(..., Uint8 *MAC[6]) * \brief Get the MAC address of the interface + * \return 1 on success, 0 if the file is the root, -1 on error + * + * Copies the six byte Media Access Control (MAC) address of the + * adapter to the \a MAC array. */ NET_IOCTL_GETMAC = 4 }; +/** + * \brief IOCtl name strings for use with eTplDrv_IOCtl.DRV_IOCTL_LOOKUP + */ #define DRV_NETWORK_IOCTLNAMES "get_mac_addr" #endif diff --git a/Kernel/include/tpl_drv_terminal.h b/Kernel/include/tpl_drv_terminal.h index 639d181f..fa90c865 100644 --- a/Kernel/include/tpl_drv_terminal.h +++ b/Kernel/include/tpl_drv_terminal.h @@ -8,7 +8,6 @@ #include /** - * \enum eTplTerminal_IOCtl * \brief Common Terminal IOCtl Calls * \extends eTplDrv_IOCtl */ @@ -16,18 +15,22 @@ enum eTplTerminal_IOCtl { /** * ioctl(..., int *mode) * \brief Get/Set the current video mode type - * see ::eTplTerminal_Modes - * \note If the mode is set the mode is changed at this call + * \param mode Pointer to an integer with the new mode number (or NULL) + * If \a mode is non-NULL the current terminal mode is changed/updated + * to the mode indicated by \a *mode + * \note See ::eTplTerminal_Modes + * \return Current/new terminal mode */ TERM_IOCTL_MODETYPE = 4, /** * ioctl(..., int *width) * \brief Get/set the display width - * \param width Pointer to an integer containing the new width - * \return Current width + * \param width Pointer to an integer containing the new width (or NULL) + * \return Current/new width * - * Set `width` to NULL to just return the current width + * If \a width is non-NULL the current width is updated (but is not + * applied until ::TERM_IOCTL_MODETYPE is called with \a mode non-NULL. */ TERM_IOCTL_WIDTH, @@ -37,28 +40,33 @@ enum eTplTerminal_IOCtl { * \param height Pointer to an integer containing the new height * \return Current height * - * Set \a height to NULL to just return the current height + * If \a height is non-NULL the current height is updated (but is not + * applied until ::TERM_IOCTL_MODETYPE is called with a non-NULL \a mode. */ TERM_IOCTL_HEIGHT, /** * ioctl(..., tTerm_IOCtl_Mode *info) - * \brief Queries the current driver about it's modes - * \param info A pointer to a ::tTerm_IOCtl_Mode with .ID set to the mode index + * \brief Queries the current driver about it's native modes + * \param info A pointer to a ::tTerm_IOCtl_Mode with \a ID set to + * the mode index (or NULL) * \return Number of modes * - * \a info can be NULL + * If \a info is NULL, the number of avaliable vative display modes + * is returned. These display modes will have sequential ID numbers + * from zero up to this value. + * + * \note The id field of \a info is not for use with ::TERM_IOCTL_MODETYPE + * This field is just for indexing the mode to get its information. */ TERM_IOCTL_QUERYMODE }; -typedef struct sTerm_IOCtl_Mode tTerm_IOCtl_Mode; - /** * \brief Virtual Terminal Mode * Describes a VTerm mode to the caller of ::TERM_IOCTL_QUERYMODE */ -struct sTerm_IOCtl_Mode +typedef struct sTerm_IOCtl_Mode { short ID; //!< Zero Based index of mode short DriverID; //!< Driver's ID number (from ::tVideo_IOCtl_Mode) @@ -69,7 +77,7 @@ struct sTerm_IOCtl_Mode unsigned bText: 1; //!< Text Mode marker unsigned unused: 7; }; -}; +} tTerm_IOCtl_Mode; /** * \brief Terminal Modes @@ -97,6 +105,9 @@ enum eTplTerminal_Modes { */ TERM_MODE_OPENGL, + /** + * \brief Number of terminal modes + */ NUM_TERM_MODES }; diff --git a/Kernel/include/tpl_drv_video.h b/Kernel/include/tpl_drv_video.h index 0272078e..bf3d286d 100644 --- a/Kernel/include/tpl_drv_video.h +++ b/Kernel/include/tpl_drv_video.h @@ -29,31 +29,77 @@ * \extends eTplDrv_IOCtl */ enum eTplVideo_IOCtl { - //! \brief Set Mode - (int mode) - VIDEO_IOCTL_SETMODE = 4, - //! \brief Get Mode - (int *mode) - VIDEO_IOCTL_GETMODE, - //! \brief Find a matching mode - (tVideo_IOCtl_Mode *info) + /** + * ioctl(..., int *mode) + * \brief Get/Set Mode + * \return Current mode ID or -1 on error + * + * If \a mode is non-NULL, the current video mode is set to \a *mode. + * This updated ID is then returned to the user. + */ + VIDEO_IOCTL_GETSETMODE = 4, + + /** + * ioctl(..., tVideo_IOCtl_Mode *info) + * \brief Find a matching mode + * \return 1 if a mode was found, 0 otherwise + * + * Using avaliable modes matching the \a bpp and \a flags fields + * set the \a id field to the mode id of the mode with the closest + * \a width and \a height. + */ VIDEO_IOCTL_FINDMODE, - //! \brief Get mode info - (tVideo_IOCtl_Mode *info) + + /** + * ioctl(..., tVideo_IOCtl_Mode *info) + * \brief Get mode info + * \return 1 if the mode exists, 0 otherwise + * + * Set \a info's fields to the mode specified by the \a id field. + */ VIDEO_IOCTL_MODEINFO, - //! \brief Sets the cursor position (tVideo_IOCtl_Pos *pos) + + /** + * ioctl(..., tVideo_IOCtl_Pos *pos) + * \brief Sets the cursor position + * \return Boolean success + * + * Set the text mode cursor position (if it is supported) + * If the \a pos is set to (-1,-1) the cursor is hidden, otherwise + * \a pos MUST be within the current screen size (as given by the + * current mode's tVideo_IOCtl_Mode.width and tVideo_IOCtl_Mode.height + * fields). + */ VIDEO_IOCTL_SETCURSOR, - //! \brief Request access to Framebuffer - (void *dest), Return Boolean Success + + /** + * ioctl(..., tVAddr MapTo) + * \brief Request access to Framebuffer + * \return Boolean Success + * + * Requests the driver to allow the user direct access to the + * framebuffer by mapping it to the supplied address. + * If the driver does not allow this boolean FALSE (0) is returned, + * else if the call succeeds (and the framebuffer ends up mapped) boolean + * TRUE (1) is returned. + */ VIDEO_IOCTL_REQLFB }; /** * \brief Mode Structure used in IOCtl Calls + * + * Defines a video mode supported by (or requested of) this driver (depending + * on what ioctl call is used) */ -struct sVideo_IOCtl_Mode { - short id; //!< Mide ID +typedef struct sVideo_IOCtl_Mode +{ + short id; //!< Mode ID Uint16 width; //!< Width Uint16 height; //!< Height - Uint8 bpp; //!< Bits per Pixel + Uint8 bpp; //!< Bits per Unit (Character or Pixel, depending on \a flags) Uint8 flags; //!< Mode Flags -}; -typedef struct sVideo_IOCtl_Mode tVideo_IOCtl_Mode; //!< Mode Type +} tVideo_IOCtl_Mode; //! \name Video Mode flags //! \{ @@ -71,17 +117,17 @@ typedef struct sVideo_IOCtl_Mode tVideo_IOCtl_Mode; //!< Mode Type /** * \brief Describes a position in the video framebuffer */ -typedef struct sVideo_IOCtl_Pos tVideo_IOCtl_Pos; -struct sVideo_IOCtl_Pos { +typedef struct sVideo_IOCtl_Pos +{ Sint16 x; //!< X Coordinate Sint16 y; //!< Y Coordinate -}; +} tVideo_IOCtl_Pos; /** * \brief Virtual Terminal Representation of a character */ -typedef struct sVT_Char tVT_Char; -struct sVT_Char { +typedef struct sVT_Char +{ Uint32 Ch; //!< UTF-32 Character union { struct { @@ -90,7 +136,7 @@ struct sVT_Char { }; Uint32 Colour; //!< Compound colour for ease of access }; -}; +} tVT_Char; /** * \name Basic builtin colour definitions @@ -110,19 +156,23 @@ extern int giVT_CharWidth; extern int giVT_CharHeight; /** * \fn void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC, Uint32 FGC) - * \brief Renders a character to a buffer + * \brief Driver helper that renders a character to a buffer * \param Codepoint Unicode character to render * \param Buffer Buffer to render to (32-bpp) * \param Pitch Number of DWords per line * \param BGC 32-bit Background Colour * \param FGC 32-bit Foreground Colour + * + * This function is provided to help video drivers to support a simple + * text mode by keeping the character rendering abstracted from the driver, + * easing the driver development and reducing code duplication. */ extern void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC, Uint32 FGC); /** * \fn Uint32 VT_Colour12to24(Uint16 Col12) * \brief Converts a colour from 12bpp to 32bpp * \param Col12 12-bpp input colour - * \return Expanded 32-bpp (24-bit colour) version of \a Col12 + * \return Expanded 32-bpp (24-bit colour) version of \a Col12 */ extern Uint32 VT_Colour12to24(Uint16 Col12); diff --git a/Kernel/include/vfs.h b/Kernel/include/vfs.h index 7850600c..75c30128 100644 --- a/Kernel/include/vfs.h +++ b/Kernel/include/vfs.h @@ -11,35 +11,6 @@ #include -//! \name ACL Permissions -//! \{ -/** - * \brief Readable - */ -#define VFS_PERM_READ 0x00000001 -/** - * \brief Writeable - */ -#define VFS_PERM_WRITE 0x00000002 -/** - * \brief Append allowed - */ -#define VFS_PERM_APPEND 0x00000004 -/** - * \brief Executable - */ -#define VFS_PERM_EXECUTE 0x00000008 -/** - * \brief All permissions granted - */ -#define VFS_PERM_ALL 0x7FFFFFFF // Mask for permissions -/** - * \brief Denies instead of granting permissions - * \note Denials take precedence - */ -#define VFS_PERM_DENY 0x80000000 // Inverts permissions -//! \} - /** * \name VFS Node Flags * \{ @@ -53,6 +24,7 @@ /** * \brief VFS Node + * \todo Complete / Finalise */ typedef struct sVFS_Node { Uint64 Inode; //!< Inode ID @@ -75,33 +47,84 @@ typedef struct sVFS_Node { int NumACLs; //!< Number of ACL entries tVFS_ACL *ACLs; //!< ACL Entries - //! Reference the node + /** + * \brief Reference the node + * \param Node Pointer to this node + */ void (*Reference)(struct sVFS_Node *Node); - //! Close (dereference) the node + /** + * \brief Close (dereference) the node + * \param Node Pointer to this node + */ void (*Close)(struct sVFS_Node *Node); - //! Send an IO Control + + /** + * \brief Send an IO Control + * \param Node Pointer to this node + * \param Id IOCtl call number + * \param Data Pointer to data to pass to the driver + * \return Implementation defined + */ int (*IOCtl)(struct sVFS_Node *Node, int Id, void *Data); - //! \brief Read from the file + /** + * \brief Read from the file + * \param Node Pointer to this node + * \param Offset Byte offset in the file + * \param Length Number of bytes to read + * \param Buffer Destination for read data + * \return Number of bytes read + */ Uint64 (*Read)(struct sVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); - //! \brief Write to the file + /** + * \brief Write to the file + * \param Node Pointer to this node + * \param Offset Byte offser in the file + * \param Length Number of bytes to write + * \param Buffer Source of written data + * \return Number of bytes read + */ Uint64 (*Write)(struct sVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); - //! \brief Find an directory entry by name - //! \note The node returned must be accessable until ::tVFS_Node.Close is called + /** + * \brief Find an directory entry by name + * \param Node Pointer to this node + * \param Name Name of the file wanted + * \return Pointer to the requested node or NULL if it cannot be found + * \note The node returned must be accessable until ::tVFS_Node.Close + * is called and ReferenceCount reaches zero. + */ struct sVFS_Node *(*FindDir)(struct sVFS_Node *Node, char *Name); - //! \brief Read from a directory - //! \note MUST return a heap address + /** + * \brief Read from a directory + * \param Node Pointer to this node + * \param Pos Offset in the directory + * \return Pointer to the name of the item on the heap (will be freed + * by the caller). If the directory end has been reached, NULL + * will be returned. + * If an item is required to be skipped either &::NULLNode, + * ::VFS_SKIP or ::VFS_SKIPN(0...1023) will be returned. + */ char *(*ReadDir)(struct sVFS_Node *Node, int Pos); - //! \brief Create a node in a directory + /** + * \brief Create a node in a directory + * \param Node Pointer to this node + * \param Name Name of the new child + * \param Flags Flags to apply to the new child (directory or symlink) + * \return Boolean success + */ int (*MkNod)(struct sVFS_Node *Node, char *Name, Uint Flags); - //! \brief Relink (Rename/Remove) a file/directory + /** + * \brief Relink (Rename/Remove) a file/directory + * \param Node Pointer to this node + * \param OldName Name of the item to move/delete + * \param NewName New name (or NULL if unlinking is wanted) + * \return Boolean Success + */ int (*Relink)(struct sVFS_Node *Node, char *OldName, char *NewName); - - //!< \todo Complete } tVFS_Node; /** diff --git a/Kernel/include/vfs_ext.h b/Kernel/include/vfs_ext.h index 178eb544..816c4a04 100644 --- a/Kernel/include/vfs_ext.h +++ b/Kernel/include/vfs_ext.h @@ -1,23 +1,76 @@ -/* - * Acess 2 - * vfs_ext.h - * - Exported Symbols from the VFS +/** + * \file vfs_ext.h + * \brief Exported VFS Definitions + * \author John Hodge (thePowersGang) */ #ifndef _VFS_EXT_H #define _VFS_EXT_H // === CONSTANTS === +//! maximum size of a Memory Path generated by VFS_GetMemPath #define VFS_MEMPATH_SIZE (3 + (BITS/8)*2) +/** + * \name Flags for VFS_Open + * \{ + */ +//! Open for execution #define VFS_OPENFLAG_EXEC 0x01 +//! Open for reading #define VFS_OPENFLAG_READ 0x02 +//! Open for writing #define VFS_OPENFLAG_WRITE 0x04 +//! Do not resolve the final symbolic link #define VFS_OPENFLAG_NOLINK 0x40 +//! Open as a user #define VFS_OPENFLAG_USER 0x80 +/** + * \} + */ +//! Marks a VFS handle as belonging to the kernel #define VFS_KERNEL_FLAG 0x40000000 -#define SEEK_SET 1 -#define SEEK_CUR 0 -#define SEEK_END -1 +/** + * \brief VFS_Seek directions + */ +enum eVFS_SeekDirs +{ + SEEK_SET = 1, //!< Set the current file offset + SEEK_CUR = 0, //!< Seek relative to the current position + SEEK_END = -1 //!< Seek from the end of the file backwards +}; + +/** + * \name ACL Permissions + * \{ + */ +/** + * \brief Readable + */ +#define VFS_PERM_READ 0x00000001 +/** + * \brief Writeable + */ +#define VFS_PERM_WRITE 0x00000002 +/** + * \brief Append allowed + */ +#define VFS_PERM_APPEND 0x00000004 +/** + * \brief Executable + */ +#define VFS_PERM_EXECUTE 0x00000008 +/** + * \brief All permissions granted + */ +#define VFS_PERM_ALL 0x7FFFFFFF // Mask for permissions +/** + * \brief Denies instead of granting permissions + * \note Denials take precedence + */ +#define VFS_PERM_DENY 0x80000000 // Inverts permissions +/** + * \} + */ // -- System Call Structures --- /** @@ -33,42 +86,185 @@ typedef struct sVFS_ACL unsigned Inv: 1; //!< Invert Permissions unsigned Perms: 31; //!< Permission Flags }; -} tVFS_ACL; +} tVFS_ACL; -struct s_sysFInfo { - Uint uid, gid; - Uint flags; - Uint64 size; - Sint64 atime; - Sint64 mtime; - Sint64 ctime; - int numacls; - tVFS_ACL acls[]; -}; +/** + * \brief SYS_FINFO structure + */ +typedef struct sFInfo +{ + Uint uid; //!< Owning User ID + Uint gid; //!< Owning Group ID + Uint flags; //!< File flags + Uint64 size; //!< File Size + Sint64 atime; //!< Last Accessed time + Sint64 mtime; //!< Last modified time + Sint64 ctime; //!< Creation time + int numacls; //!< Total number of ACL entries + tVFS_ACL acls[]; //!< ACL buffer (size is passed in the \a MaxACLs argument to VFS_FInfo) +} tFInfo; // === FUNCTIONS === +/** + * \brief Initialise the VFS (called by system.c) + * \return Boolean Success + */ extern int VFS_Init(); -extern int VFS_Open(char *Path, Uint Flags); +/** + * \brief Open a file + * \param Path Absolute or relative path to the file + * \param Mode Flags defining how to open the file + * \return VFS Handle (an integer) or -1 if an error occured + */ +extern int VFS_Open(char *Path, Uint Mode); +/** + * \brief Close a currently open file + * \param FD Handle returned by ::VFS_Open + */ extern void VFS_Close(int FD); +/** + * \brief Get file information from an open file + * \param FD File handle returned by ::VFS_Open + * \param Dest Destination for the read information + * \param MaxACLs Number of ACL slots allocated in the \a Dest structure + * \return Boolean Success + * + * If the \a NumACLs is smaller than the number of ACLs the node has, only + * \a NumACLs will be copied into \a Dest, but the tFInfo.numacls field + * will be set to the true ammount of ACLs. It is up to the user to do with + * this information how they like. + */ +extern int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs); +/** + * \brief Gets the permissions appling to a user/group. + * \param FD File handle returned by ::VFS_Open + * \param Dest ACL information structure to edit + * \return Boolean success + * + * This function sets the tVFS_ACL.Inv and tVFS_ACL.Perms fields to what + * permissions the user/group specied in tVFS_ACL.ID has on the file. + */ +extern int VFS_GetACL(int FD, tVFS_ACL *Dest); +/** + * \brief Changes the user's current working directory + * \param Dest New working directory (either absolute or relative to the current) + * \return Boolean Success + */ +extern int VFS_ChDir(char *Dest); +/** + * \brief Change the current virtual root for the user + * \param New New virtual root (same as ::VFS_ChDir but cannot go + * above the current virtual root) + * \return Boolean success + */ +extern int VFS_ChRoot(char *New); + +/** + * \brief Change the location of the current file pointer + * \param FD File handle returned by ::VFS_Open + * \param Offset Offset within the file to go to + * \param Whence A direction from ::eVFS_SeekDirs + * \return Boolean success + */ extern int VFS_Seek(int FD, Sint64 Offset, int Direction); +/** + * \brief Returns the current file pointer + * \param FD File handle returned by ::VFS_Open + * \return Current file position + */ extern Uint64 VFS_Tell(int FD); +/** + * \brief Reads data from a file + * \param FD File handle returned by ::VFS_Open + * \param Length Number of bytes to read from the file + * \param Buffer Destination of read data + * \return Number of read bytes + */ extern Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer); +/** + * \brief Writes data to a file + * \param FD File handle returned by ::VFS_Open + * \param Length Number of bytes to write to the file + * \param Buffer Source of written data + * \return Number of bytes written + */ extern Uint64 VFS_Write(int FD, Uint64 Length, void *Buffer); +/** + * \brief Reads from a specific offset in the file + * \param FD File handle returned by ::VFS_Open + * \param Offset Byte offset in the file + * \param Length Number of bytes to read from the file + * \param Buffer Source of read data + * \return Number of bytes read + */ extern Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer); +/** + * \brief Writes to a specific offset in the file + * \param FD File handle returned by ::VFS_Open + * \param Offset Byte offset in the file + * \param Length Number of bytes to write to the file + * \param Buffer Source of written data + * \return Number of bytes written + */ extern Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer); +/** + * \brief Sends an IOCtl request to the driver + * \param FD File handle returned by ::VFS_Open + * \param ID IOCtl call ID (driver specific) + * \param Buffer Data pointer to send to the driver + * \return Driver specific response + */ extern int VFS_IOCtl(int FD, int ID, void *Buffer); -extern void VFS_GetMemPath(void *Base, Uint Length, char *Dest); +/** + * \brief Creates a VFS Memory path from a pointer and size + * \param Dest Destination for the created path + * \param Base Base of the memory file + * \param Length Length of the memory buffer + * \note A maximum of VFS_MEMPATH_SIZE bytes will be required in \a Dest + */ +extern void VFS_GetMemPath(char *Dest, void *Base, Uint Length); +/** + * \brief Gets the canoical (true) path of a file + * \param Path File path (may contain symlinks, relative elements etc.) + * \return Absolute path with no symlinks + */ extern char *VFS_GetTruePath(char *Path); +/** + * \brief Mounts a filesystem + * \param Device Device to mount + * \param MountPoint Location to mount + * \param Filesystem Filesystem to use + * \param Options Options string to pass the driver + * \return 1 on succes, -1 on error + */ extern int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *Options); +/** + * \brief Create a new directory + * \param Path Path to new directory (absolute or relative) + * \return Boolean success + * \note The parent of the directory must exist + */ extern int VFS_MkDir(char *Path); -extern int VFS_Symlink(char *Link, char *Dest); +/** + * \brief Create a symbolic link + * \param Name Name of the symbolic link + * \param Link File the symlink points to + * \return Boolean success (\a Link is not tested for existence) + */ +extern int VFS_Symlink(char *Name, char *Link); +/** + * \brief Read from a directory + * \param FD File handle returned by ::VFS_Open + * \param Dest Destination array for the file name (max 255 bytes) + * \return Boolean Success + */ extern int VFS_ReadDir(int FD, char *Dest); #endif diff --git a/Kernel/modules.c b/Kernel/modules.c index eec50200..44c4cb51 100644 --- a/Kernel/modules.c +++ b/Kernel/modules.c @@ -98,9 +98,13 @@ int Modules_LoadBuiltins() gKernelModules[i].Name, gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF ); - gKernelModules[i].Init(NULL); + if( gKernelModules[i].Init(NULL) == 0 ) { + Log("Loading Failed, all modules that depend on this will also fail"); + baIsLoaded[i] = -1; + } // Mark as loaded - baIsLoaded[i] = 1; + else + baIsLoaded[i] = 1; numToInit --; } } @@ -116,7 +120,7 @@ int Module_LoadMem(void *Buffer, Uint Length, char *ArgString) { char path[VFS_MEMPATH_SIZE]; - VFS_GetMemPath(Buffer, Length, path); + VFS_GetMemPath(path, Buffer, Length); return Module_LoadFile( path, ArgString ); } diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index 87701873..6eee6666 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -25,9 +25,6 @@ extern Uint Proc_SendMessage(Uint *Err, Uint Dest, Uint Length, void *Data); extern int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer); extern int Proc_Execve(char *File, char **ArgV, char **EnvP); extern Uint Binary_Load(char *file, Uint *entryPoint); -extern int VFS_FInfo(int FD, void *Dest, int MaxACLs); -extern int VFS_GetACL(int FD, void *Dest); -extern int VFS_ChDir(char *Dest); extern int Threads_SetName(char *NewName); extern int Threads_GetPID(); extern int Threads_GetTID(); @@ -210,7 +207,7 @@ void SyscallHandler(tSyscallRegs *Regs) break; case SYS_FINFO: - CHECK_NUM_NONULL( Regs->Arg2, sizeof(struct s_sysFInfo) + Regs->Arg3*sizeof(tVFS_ACL) ); + CHECK_NUM_NONULL( Regs->Arg2, sizeof(tFInfo) + Regs->Arg3*sizeof(tVFS_ACL) ); // FP, Dest, MaxACLs ret = VFS_FInfo( Regs->Arg1, (void*)Regs->Arg2, Regs->Arg3 ); break; diff --git a/Kernel/vfs/io.c b/Kernel/vfs/io.c index 67a7075b..84c930fd 100644 --- a/Kernel/vfs/io.c +++ b/Kernel/vfs/io.c @@ -137,13 +137,13 @@ Uint64 VFS_Tell(int FD) } /** - * \fn int VFS_Seek(int FD, Sint64 Distance, int Whence) + * \fn int VFS_Seek(int FD, Sint64 Offset, int Whence) * \brief Seek to a new location * \param FD File descriptor - * \param Distance Where to go + * \param Offset Where to go * \param Whence From where */ -int VFS_Seek(int FD, Sint64 Distance, int Whence) +int VFS_Seek(int FD, Sint64 Offset, int Whence) { tVFS_Handle *h; @@ -152,18 +152,18 @@ int VFS_Seek(int FD, Sint64 Distance, int Whence) // Set relative to current position if(Whence == 0) { - h->Position += Distance; + h->Position += Offset; return 0; } // Set relative to end of file if(Whence < 0) { - h->Position = h->Node->Size - Distance; + h->Position = h->Node->Size - Offset; return 0; } // Set relative to start of file - h->Position = Distance; + h->Position = Offset; return 0; } @@ -183,11 +183,11 @@ int VFS_IOCtl(int FD, int ID, void *Buffer) } /** - * \fn int VFS_FInfo(int FD, struct s_sysFInfo *Dest, int MaxACLs) + * \fn int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs) * \brief Retrieve file information * \return Number of ACLs stored */ -int VFS_FInfo(int FD, struct s_sysFInfo *Dest, int MaxACLs) +int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs) { tVFS_Handle *h; int max; diff --git a/Kernel/vfs/main.c b/Kernel/vfs/main.c index 795a64fa..4722aae5 100644 --- a/Kernel/vfs/main.c +++ b/Kernel/vfs/main.c @@ -15,7 +15,7 @@ extern tVFS_Driver gDevFS_Info; // === PROTOTYPES === int VFS_Init(); char *VFS_GetTruePath(char *Path); -void VFS_GetMemPath(void *Base, Uint Length, char *Dest); +void VFS_GetMemPath(char *Dest, void *Base, Uint Length); tVFS_Driver *VFS_GetFSByName(char *Name); int VFS_AddDriver(tVFS_Driver *Info); void VFS_UpdateDriverFile(); @@ -76,10 +76,10 @@ char *VFS_GetTruePath(char *Path) } /** - * \fn void VFS_GetMemPath(void *Base, Uint Length, char *Dest) + * \fn void VFS_GetMemPath(char *Dest, void *Base, Uint Length) * \brief Create a VFS memory pointer path */ -void VFS_GetMemPath(void *Base, Uint Length, char *Dest) +void VFS_GetMemPath(char *Dest, void *Base, Uint Length) { Log("VFS_GetMemPath: (Base=%p, Length=0x%x, Dest=%p)", Base, Length, Dest); Dest[0] = '$'; diff --git a/Kernel/vfs/mount.c b/Kernel/vfs/mount.c index eb6a5b1f..6c0929e2 100644 --- a/Kernel/vfs/mount.c +++ b/Kernel/vfs/mount.c @@ -21,21 +21,21 @@ tVFS_Mount *gVFS_RootMount = NULL; // === CODE === /** - * \fn int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *ArgString) + * \fn int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *Options) * \brief Mount a device * \param Device Device string to mount * \param MountPoint Destination for the mount * \param Filesystem Filesystem to use for the mount - * \param ArgString Options to be passed to the filesystem + * \param Options Options to be passed to the filesystem * \return -1 on Invalid FS, -2 on No Mem, 0 on success */ -int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *ArgString) +int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *Options) { tVFS_Mount *mnt; tVFS_Driver *fs; int deviceLen = strlen(Device); int mountLen = strlen(MountPoint); - int argLen = strlen(ArgString); + int argLen = strlen(Options); // Get the filesystem fs = VFS_GetFSByName(Filesystem); @@ -66,7 +66,7 @@ int VFS_Mount(char *Device, char *MountPoint, char *Filesystem, char *ArgString) memcpy( mnt->MountPoint, MountPoint, mountLen+1 ); mnt->Options = &mnt->StrData[deviceLen+1+mountLen+1]; - memcpy( mnt->Options, ArgString, argLen+1 ); + memcpy( mnt->Options, Options, argLen+1 ); // Initialise Volume mnt->RootNode = fs->InitDevice(Device, NULL); //&ArgString); diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c index 05f7d295..655272ef 100644 --- a/Kernel/vfs/open.c +++ b/Kernel/vfs/open.c @@ -550,17 +550,16 @@ void VFS_Close(int FD) } /** - * \fn int VFS_ChDir(char *New) * \brief Change current working directory */ -int VFS_ChDir(char *New) +int VFS_ChDir(char *Dest) { char *buf; int fd; tVFS_Handle *h; // Create Absolute - buf = VFS_GetAbsPath(New); + buf = VFS_GetAbsPath(Dest); if(buf == NULL) { Log("VFS_ChDir: Path expansion failed"); return -1; diff --git a/Makefile.cfg b/Makefile.cfg index 18181a91..b2cb47d1 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -18,5 +18,6 @@ FILESYSTEMS = fat DRIVERS = ata_x86 MODULES = FS_Ext2 FDD NE2000 BochsGA -DISTROOT = /mnt/AcessHDD/Acess2 -ACESSDIR = /home/hodgeja/Projects/Acess2 +#DISTROOT = /mnt/AcessHDD/Acess2 +DISTROOT = ~/Projects/Acess2/Filesystem +ACESSDIR = ~/Projects/Acess2 diff --git a/Modules/BochsGA/bochsvbe.c b/Modules/BochsGA/bochsvbe.c index a833503f..fdf92253 100644 --- a/Modules/BochsGA/bochsvbe.c +++ b/Modules/BochsGA/bochsvbe.c @@ -250,12 +250,11 @@ INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data) ret = 0; break; - case VIDEO_IOCTL_SETMODE: - ret = BGA_int_UpdateMode(*(int*)(Data)); - break; - - case VIDEO_IOCTL_GETMODE: - ret = giBGA_CurrentMode; + case VIDEO_IOCTL_GETSETMODE: + if( Data ) + ret = BGA_int_UpdateMode(*(int*)(Data)); + else + ret = giBGA_CurrentMode; break; case VIDEO_IOCTL_FINDMODE: diff --git a/Modules/FDD/fdd.c b/Modules/FDD/fdd.c index c33b2818..2cf28b64 100644 --- a/Modules/FDD/fdd.c +++ b/Modules/FDD/fdd.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -17,7 +17,7 @@ #define FDD_VERSION ((0<<8)|(75)) // --- Options -#define USE_CACHE 1 // Use Sector Cache +#define USE_CACHE 0 // Use Sector Cache #define CACHE_SIZE 32 // Number of cachable sectors #define FDD_SEEK_TIMEOUT 10 // Timeout for a seek operation #define MOTOR_ON_DELAY 500 // Miliseconds @@ -33,6 +33,9 @@ typedef struct { int track[2]; int timer; tVFS_Node Node; + #if !USE_CACHE + tIOCache *CacheHandle; + #endif } t_floppyDevice; /** @@ -83,6 +86,8 @@ char *FDD_ReadDir(tVFS_Node *Node, int pos); tVFS_Node *FDD_FindDir(tVFS_Node *dirNode, char *Name); int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data); Uint64 FDD_ReadFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer); +// --- 1st Level Disk Access +Uint FDD_ReadSectors(Uint64 SectorAddr, Uint Count, void *Buffer, Uint Disk); // --- Raw Disk Access int FDD_ReadSector(Uint32 disk, Uint64 lba, void *Buffer); int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer); @@ -195,7 +200,7 @@ int FDD_Install(char **Arguments) // Register with devfs DevFS_AddDevice(&gFDD_DriverInfo); - return 0; + return 1; } /** @@ -225,26 +230,26 @@ char *FDD_ReadDir(tVFS_Node *Node, int pos) * \fn tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *filename); * \brief Find File Routine (for vfs_node) */ -tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *filename) +tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *Filename) { int i; - ENTER("sfilename", filename); + ENTER("sFilename", Filename); // Sanity check string - if(filename == NULL) { + if(Filename == NULL) { LEAVE('n'); return NULL; } // Check string length (should be 1) - if(filename[0] == '\0' || filename[1] != '\0') { + if(Filename[0] == '\0' || Filename[1] != '\0') { LEAVE('n'); return NULL; } // Get First character - i = filename[0] - '0'; + i = Filename[0] - '0'; // Check for 1st disk and if it is present return if(i == 0 && gFDD_Devices[0].type != 0) { @@ -263,103 +268,153 @@ tVFS_Node *FDD_FindDir(tVFS_Node *Node, char *filename) return NULL; } +static const char *casIOCTLS[] = {DRV_IOCTLNAMES,DRV_DISK_IOCTLNAMES,NULL}; /** - * \fn int FDD_IOCtl(tVFS_Node *node, int id, void *data) + * \fn int FDD_IOCtl(tVFS_Node *Node, int id, void *data) * \brief Stub ioctl function */ -int FDD_IOCtl(tVFS_Node *node, int id, void *data) +int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data) { - switch(id) + switch(ID) { - case DRV_IOCTL_TYPE: return DRV_TYPE_DISK; - case DRV_IOCTL_IDENT: memcpy(data, "FDD\0", 4); return 1; - case DRV_IOCTL_VERSION: return FDD_VERSION; - default: return 0; + case DRV_IOCTL_TYPE: + return DRV_TYPE_DISK; + + case DRV_IOCTL_IDENT: + if(!CheckMem(Data, 4)) return -1; + memcpy(Data, "FDD\0", 4); + return 1; + + case DRV_IOCTL_VERSION: + return FDD_VERSION; + + case DRV_IOCTL_LOOKUP: + if(!CheckString(Data)) return -1; + return LookupString((char**)casIOCTLS, Data); + + case DISK_IOCTL_GETBLOCKSIZE: + return 512; + + default: + return 0; } } /** - * \fn Uint64 fdd_readFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer) + * \fn Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) * \brief Read Data from a disk */ -Uint64 FDD_ReadFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer) +Uint64 FDD_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { - int i = 0; - int disk; - Uint32 buf[128]; + int i = 0; + int disk; + //Uint32 buf[128]; - ENTER("xoff xlen pbuffer", off, len, buffer); + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); - if(node == NULL) { + if(Node == NULL) { LEAVE('i', -1); return -1; } - if(node->Inode != 0 && node->Inode != 1) { + if(Node->Inode != 0 && Node->Inode != 1) { LEAVE('i', -1); return -1; } - disk = node->Inode; + disk = Node->Inode; // Update Accessed Time - node->ATime = now(); + Node->ATime = now(); - if((off & 0x1FF) || (len & 0x1FF)) + #if 0 + if((Offset & 0x1FF) || (Length & 0x1FF)) { // Un-Aligned Offset/Length - int startOff = off>>9; - int sectOff = off&0x1FF; - int sectors = (len+0x1FF)>>9; + int startOff = Offset >> 9; + int sectOff = Offset & 0x1FF; + int sectors = (Length + 0x1FF) >> 9; LOG("Non-aligned Read"); //Read Starting Sector if(!FDD_ReadSector(disk, startOff, buf)) return 0; - memcpy(buffer, (char*)(buf+sectOff), len>512-sectOff?512-sectOff:len); + memcpy(Buffer, (char*)(buf+sectOff), Length > 512-sectOff ? 512-sectOff : Length); - //If the data size is one sector or less - if(len <= 512-sectOff) { - LEAVE('X', len); - return len; //Return + // If the data size is one sector or less + if(Length <= 512-sectOff) + { + LEAVE('X', Length); + return Length; //Return } - buffer += 512-sectOff; + Buffer += 512-sectOff; //Read Middle Sectors - for(i=1;i> 9; - int sector = off >> 9; + int count = Length >> 9; + int sector = Offset >> 9; LOG("Aligned Read"); //Aligned Offset and Length - Simple Code - for(i=0;i>1]; LOG("Calculating Disk Dimensions"); - //Get CHS position + // Get CHS position if(FDD_int_GetDims(gFDD_Devices[Disk].type, lba, &cyl, &head, &sec, &spt) != 1) { LEAVE('i', -1); return -1; @@ -497,6 +552,17 @@ int FDD_ReadSector(Uint32 Disk, Uint64 SectorAddr, void *Buffer) return 1; } +/** + * \fn int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer) + * \brief Write a sector to the floppy disk + * \note Not Implemented + */ +int FDD_WriteSector(Uint32 Disk, Uint64 LBA, void *Buffer) +{ + Warning("[FDD ] Read Only at the moment"); + return -1; +} + /** * \fn int FDD_int_SeekTrack(int disk, int track) * \brief Seek disk to selected track diff --git a/Modules/NE2000/ne2000.c b/Modules/NE2000/ne2000.c index 7f951543..abca050c 100644 --- a/Modules/NE2000/ne2000.c +++ b/Modules/NE2000/ne2000.c @@ -216,7 +216,7 @@ int Ne2k_Install(char **Options) gNe2k_DriverInfo.RootNode.Size = giNe2k_CardCount; DevFS_AddDevice( &gNe2k_DriverInfo ); - return 0; + return 1; } /** -- 2.20.1